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

Side by Side Diff: chrome/browser/download/save_package_unittest.cc

Issue 7373004: Move the save file code from chrome to content. This is just a file move so the DEPS in content\b... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 5 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 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 <string>
6
7 #include "base/file_path.h"
8 #include "base/path_service.h"
9 #include "base/scoped_temp_dir.h"
10 #include "base/string_util.h"
11 #include "base/utf_string_conversions.h"
12 #include "chrome/browser/download/save_package.h"
13 #include "chrome/browser/ui/tab_contents/test_tab_contents_wrapper.h"
14 #include "content/browser/browser_thread.h"
15 #include "content/browser/net/url_request_mock_http_job.h"
16 #include "content/browser/tab_contents/test_tab_contents.h"
17 #include "googleurl/src/gurl.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19
20 #define FPL FILE_PATH_LITERAL
21 #if defined(OS_WIN)
22 #define HTML_EXTENSION ".htm"
23 // This second define is needed because MSVC is broken.
24 #define FPL_HTML_EXTENSION L".htm"
25 #else
26 #define HTML_EXTENSION ".html"
27 #define FPL_HTML_EXTENSION ".html"
28 #endif
29
30 namespace {
31
32 // This constant copied from save_package.cc.
33 #if defined(OS_WIN)
34 const uint32 kMaxFilePathLength = MAX_PATH - 1;
35 const uint32 kMaxFileNameLength = MAX_PATH - 1;
36 #elif defined(OS_POSIX)
37 const uint32 kMaxFilePathLength = PATH_MAX - 1;
38 const uint32 kMaxFileNameLength = NAME_MAX;
39 #endif
40
41 // Used to make long filenames.
42 std::string long_file_name(
43 "EFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz01234567"
44 "89ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz012345"
45 "6789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz0123"
46 "456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789a");
47
48 bool HasOrdinalNumber(const FilePath::StringType& filename) {
49 FilePath::StringType::size_type r_paren_index = filename.rfind(FPL(')'));
50 FilePath::StringType::size_type l_paren_index = filename.rfind(FPL('('));
51 if (l_paren_index >= r_paren_index)
52 return false;
53
54 for (FilePath::StringType::size_type i = l_paren_index + 1;
55 i != r_paren_index; ++i) {
56 if (!IsAsciiDigit(filename[i]))
57 return false;
58 }
59
60 return true;
61 }
62
63 } // namespace
64
65 class SavePackageTest : public TabContentsWrapperTestHarness {
66 public:
67 SavePackageTest() : browser_thread_(BrowserThread::UI, &message_loop_) {
68 }
69
70 bool GetGeneratedFilename(bool need_success_generate_filename,
71 const std::string& disposition,
72 const std::string& url,
73 bool need_htm_ext,
74 FilePath::StringType* generated_name) {
75 SavePackage* save_package;
76 if (need_success_generate_filename)
77 save_package = save_package_success_.get();
78 else
79 save_package = save_package_fail_.get();
80 return save_package->GenerateFileName(disposition, GURL(url), need_htm_ext,
81 generated_name);
82 }
83
84 FilePath EnsureHtmlExtension(const FilePath& name) {
85 return SavePackage::EnsureHtmlExtension(name);
86 }
87
88 FilePath EnsureMimeExtension(const FilePath& name,
89 const std::string& content_mime_type) {
90 return SavePackage::EnsureMimeExtension(name, content_mime_type);
91 }
92
93 GURL GetUrlToBeSaved() {
94 return save_package_success_->GetUrlToBeSaved();
95 }
96
97 protected:
98 virtual void SetUp() {
99 TabContentsWrapperTestHarness::SetUp();
100
101 // Do the initialization in SetUp so contents() is initialized by
102 // TabContentsWrapperTestHarness::SetUp.
103 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
104
105 save_package_success_ = new SavePackage(contents_wrapper(),
106 temp_dir_.path().AppendASCII("testfile" HTML_EXTENSION),
107 temp_dir_.path().AppendASCII("testfile_files"));
108
109 // We need to construct a path that is *almost* kMaxFilePathLength long
110 long_file_name.resize(kMaxFilePathLength + long_file_name.length());
111 while (long_file_name.length() < kMaxFilePathLength)
112 long_file_name += long_file_name;
113 long_file_name.resize(
114 kMaxFilePathLength - 9 - temp_dir_.path().value().length());
115
116 save_package_fail_ = new SavePackage(contents_wrapper(),
117 temp_dir_.path().AppendASCII(long_file_name + HTML_EXTENSION),
118 temp_dir_.path().AppendASCII(long_file_name + "_files"));
119 }
120
121 private:
122 BrowserThread browser_thread_;
123
124 // SavePackage for successfully generating file name.
125 scoped_refptr<SavePackage> save_package_success_;
126 // SavePackage for failed generating file name.
127 scoped_refptr<SavePackage> save_package_fail_;
128
129 ScopedTempDir temp_dir_;
130
131 DISALLOW_COPY_AND_ASSIGN(SavePackageTest);
132 };
133
134 static const struct {
135 const char* disposition;
136 const char* url;
137 const FilePath::CharType* expected_name;
138 bool need_htm_ext;
139 } kGeneratedFiles[] = {
140 // We mainly focus on testing duplicated names here, since retrieving file
141 // name from disposition and url has been tested in DownloadManagerTest.
142
143 // No useful information in disposition or URL, use default.
144 {"1.html", "http://www.savepage.com/",
145 FPL("saved_resource") FPL_HTML_EXTENSION, true},
146
147 // No duplicate occurs.
148 {"filename=1.css", "http://www.savepage.com", FPL("1.css"), false},
149
150 // No duplicate occurs.
151 {"filename=1.js", "http://www.savepage.com", FPL("1.js"), false},
152
153 // Append numbers for duplicated names.
154 {"filename=1.css", "http://www.savepage.com", FPL("1(1).css"), false},
155
156 // No duplicate occurs.
157 {"filename=1(1).js", "http://www.savepage.com", FPL("1(1).js"), false},
158
159 // Append numbers for duplicated names.
160 {"filename=1.css", "http://www.savepage.com", FPL("1(2).css"), false},
161
162 // Change number for duplicated names.
163 {"filename=1(1).css", "http://www.savepage.com", FPL("1(3).css"), false},
164
165 // No duplicate occurs.
166 {"filename=1(11).css", "http://www.savepage.com", FPL("1(11).css"), false},
167 };
168
169 TEST_F(SavePackageTest, TestSuccessfullyGenerateSavePackageFilename) {
170 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kGeneratedFiles); ++i) {
171 FilePath::StringType file_name;
172 bool ok = GetGeneratedFilename(true,
173 kGeneratedFiles[i].disposition,
174 kGeneratedFiles[i].url,
175 kGeneratedFiles[i].need_htm_ext,
176 &file_name);
177 ASSERT_TRUE(ok);
178 EXPECT_EQ(kGeneratedFiles[i].expected_name, file_name);
179 }
180 }
181
182 TEST_F(SavePackageTest, TestUnSuccessfullyGenerateSavePackageFilename) {
183 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kGeneratedFiles); ++i) {
184 FilePath::StringType file_name;
185 bool ok = GetGeneratedFilename(false,
186 kGeneratedFiles[i].disposition,
187 kGeneratedFiles[i].url,
188 kGeneratedFiles[i].need_htm_ext,
189 &file_name);
190 ASSERT_FALSE(ok);
191 }
192 }
193
194 // Crashing on Windows, see http://crbug.com/79365
195 #if defined(OS_WIN)
196 #define MAYBE_TestLongSavePackageFilename DISABLED_TestLongSavePackageFilename
197 #else
198 #define MAYBE_TestLongSavePackageFilename TestLongSavePackageFilename
199 #endif
200 TEST_F(SavePackageTest, MAYBE_TestLongSavePackageFilename) {
201 const std::string base_url("http://www.google.com/");
202 const std::string long_file = long_file_name + ".css";
203 const std::string url = base_url + long_file;
204
205 FilePath::StringType filename;
206 // Test that the filename is successfully shortened to fit.
207 ASSERT_TRUE(GetGeneratedFilename(true, "", url, false, &filename));
208 EXPECT_TRUE(filename.length() < long_file.length());
209 EXPECT_FALSE(HasOrdinalNumber(filename));
210
211 // Test that the filename is successfully shortened to fit, and gets an
212 // an ordinal appended.
213 ASSERT_TRUE(GetGeneratedFilename(true, "", url, false, &filename));
214 EXPECT_TRUE(filename.length() < long_file.length());
215 EXPECT_TRUE(HasOrdinalNumber(filename));
216
217 // Test that the filename is successfully shortened to fit, and gets a
218 // different ordinal appended.
219 FilePath::StringType filename2;
220 ASSERT_TRUE(GetGeneratedFilename(true, "", url, false, &filename2));
221 EXPECT_TRUE(filename2.length() < long_file.length());
222 EXPECT_TRUE(HasOrdinalNumber(filename2));
223 EXPECT_NE(filename, filename2);
224 }
225
226 // Crashing on Windows, see http://crbug.com/79365
227 #if defined(OS_WIN)
228 #define MAYBE_TestLongSafePureFilename DISABLED_TestLongSafePureFilename
229 #else
230 #define MAYBE_TestLongSafePureFilename TestLongSafePureFilename
231 #endif
232 TEST_F(SavePackageTest, MAYBE_TestLongSafePureFilename) {
233 const FilePath save_dir(FPL("test_dir"));
234 const FilePath::StringType ext(FPL_HTML_EXTENSION);
235 FilePath::StringType filename =
236 #if defined(OS_WIN)
237 ASCIIToWide(long_file_name);
238 #else
239 long_file_name;
240 #endif
241
242 // Test that the filename + extension doesn't exceed kMaxFileNameLength
243 uint32 max_path = SavePackage::GetMaxPathLengthForDirectory(save_dir);
244 ASSERT_TRUE(SavePackage::GetSafePureFileName(save_dir, ext, max_path,
245 &filename));
246 EXPECT_TRUE(filename.length() <= kMaxFileNameLength-ext.length());
247 }
248
249 static const struct {
250 const FilePath::CharType* page_title;
251 const FilePath::CharType* expected_name;
252 } kExtensionTestCases[] = {
253 // Extension is preserved if it is already proper for HTML.
254 {FPL("filename.html"), FPL("filename.html")},
255 {FPL("filename.HTML"), FPL("filename.HTML")},
256 {FPL("filename.XHTML"), FPL("filename.XHTML")},
257 {FPL("filename.xhtml"), FPL("filename.xhtml")},
258 {FPL("filename.htm"), FPL("filename.htm")},
259 // ".htm" is added if the extension is improper for HTML.
260 {FPL("hello.world"), FPL("hello.world") FPL_HTML_EXTENSION},
261 {FPL("hello.txt"), FPL("hello.txt") FPL_HTML_EXTENSION},
262 {FPL("is.html.good"), FPL("is.html.good") FPL_HTML_EXTENSION},
263 // ".htm" is added if the name doesn't have an extension.
264 {FPL("helloworld"), FPL("helloworld") FPL_HTML_EXTENSION},
265 {FPL("helloworld."), FPL("helloworld.") FPL_HTML_EXTENSION},
266 };
267
268 // Crashing on Windows, see http://crbug.com/79365
269 #if defined(OS_WIN)
270 #define MAYBE_TestEnsureHtmlExtension DISABLED_TestEnsureHtmlExtension
271 #else
272 #define MAYBE_TestEnsureHtmlExtension TestEnsureHtmlExtension
273 #endif
274 TEST_F(SavePackageTest, MAYBE_TestEnsureHtmlExtension) {
275 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kExtensionTestCases); ++i) {
276 FilePath original = FilePath(kExtensionTestCases[i].page_title);
277 FilePath expected = FilePath(kExtensionTestCases[i].expected_name);
278 FilePath actual = EnsureHtmlExtension(original);
279 EXPECT_EQ(expected.value(), actual.value()) << "Failed for page title: " <<
280 kExtensionTestCases[i].page_title;
281 }
282 }
283
284 // Crashing on Windows, see http://crbug.com/79365
285 #if defined(OS_WIN)
286 #define MAYBE_TestEnsureMimeExtension DISABLED_TestEnsureMimeExtension
287 #else
288 #define MAYBE_TestEnsureMimeExtension TestEnsureMimeExtension
289 #endif
290 TEST_F(SavePackageTest, MAYBE_TestEnsureMimeExtension) {
291 static const struct {
292 const FilePath::CharType* page_title;
293 const FilePath::CharType* expected_name;
294 const char* contents_mime_type;
295 } kExtensionTests[] = {
296 { FPL("filename.html"), FPL("filename.html"), "text/html" },
297 { FPL("filename.htm"), FPL("filename.htm"), "text/html" },
298 { FPL("filename.xhtml"), FPL("filename.xhtml"), "text/html" },
299 #if defined(OS_WIN)
300 { FPL("filename"), FPL("filename.htm"), "text/html" },
301 #else // defined(OS_WIN)
302 { FPL("filename"), FPL("filename.html"), "text/html" },
303 #endif // defined(OS_WIN)
304 { FPL("filename.html"), FPL("filename.html"), "text/xml" },
305 { FPL("filename.xml"), FPL("filename.xml"), "text/xml" },
306 { FPL("filename"), FPL("filename.xml"), "text/xml" },
307 { FPL("filename.xhtml"), FPL("filename.xhtml"),
308 "application/xhtml+xml" },
309 { FPL("filename.html"), FPL("filename.html"),
310 "application/xhtml+xml" },
311 { FPL("filename"), FPL("filename.xhtml"), "application/xhtml+xml" },
312 { FPL("filename.txt"), FPL("filename.txt"), "text/plain" },
313 { FPL("filename"), FPL("filename.txt"), "text/plain" },
314 { FPL("filename.css"), FPL("filename.css"), "text/css" },
315 { FPL("filename"), FPL("filename.css"), "text/css" },
316 { FPL("filename.abc"), FPL("filename.abc"), "unknown/unknown" },
317 { FPL("filename"), FPL("filename"), "unknown/unknown" },
318 };
319 for (uint32 i = 0; i < ARRAYSIZE_UNSAFE(kExtensionTests); ++i) {
320 FilePath original = FilePath(kExtensionTests[i].page_title);
321 FilePath expected = FilePath(kExtensionTests[i].expected_name);
322 std::string mime_type(kExtensionTests[i].contents_mime_type);
323 FilePath actual = EnsureMimeExtension(original, mime_type);
324 EXPECT_EQ(expected.value(), actual.value()) << "Failed for page title: " <<
325 kExtensionTests[i].page_title << " MIME:" << mime_type;
326 }
327 }
328
329 // Test that the suggested names generated by SavePackage are reasonable:
330 // If the name is a URL, retrieve only the path component since the path name
331 // generation code will turn the entire URL into the file name leading to bad
332 // extension names. For example, a page with no title and a URL:
333 // http://www.foo.com/a/path/name.txt will turn into file:
334 // "http www.foo.com a path name.txt", when we want to save it as "name.txt".
335
336 static const struct SuggestedSaveNameTestCase {
337 const char* page_url;
338 const string16 page_title;
339 const FilePath::CharType* expected_name;
340 bool ensure_html_extension;
341 } kSuggestedSaveNames[] = {
342 // Title overrides the URL.
343 { "http://foo.com",
344 ASCIIToUTF16("A page title"),
345 FPL("A page title") FPL_HTML_EXTENSION,
346 true
347 },
348 // Extension is preserved.
349 { "http://foo.com",
350 ASCIIToUTF16("A page title with.ext"),
351 FPL("A page title with.ext"),
352 false
353 },
354 // If the title matches the URL, use the last component of the URL.
355 { "http://foo.com/bar",
356 ASCIIToUTF16("http://foo.com/bar"),
357 FPL("bar"),
358 false
359 },
360 // If the title matches the URL, but there is no "filename" component,
361 // use the domain.
362 { "http://foo.com",
363 ASCIIToUTF16("http://foo.com"),
364 FPL("foo.com"),
365 false
366 },
367 // Make sure fuzzy matching works.
368 { "http://foo.com/bar",
369 ASCIIToUTF16("foo.com/bar"),
370 FPL("bar"),
371 false
372 },
373 // A URL-like title that does not match the title is respected in full.
374 { "http://foo.com",
375 ASCIIToUTF16("http://www.foo.com/path/title.txt"),
376 FPL("http www.foo.com path title.txt"),
377 false
378 },
379 };
380
381 // Crashing on Windows, see http://crbug.com/79365
382 #if defined(OS_WIN)
383 #define MAYBE_TestSuggestedSaveNames DISABLED_TestSuggestedSaveNames
384 #else
385 #define MAYBE_TestSuggestedSaveNames TestSuggestedSaveNames
386 #endif
387 TEST_F(SavePackageTest, MAYBE_TestSuggestedSaveNames) {
388 for (size_t i = 0; i < arraysize(kSuggestedSaveNames); ++i) {
389 scoped_refptr<SavePackage> save_package(
390 new SavePackage(contents_wrapper(), FilePath(), FilePath()));
391 save_package->page_url_ = GURL(kSuggestedSaveNames[i].page_url);
392 save_package->title_ = kSuggestedSaveNames[i].page_title;
393
394 FilePath save_name = save_package->GetSuggestedNameForSaveAs(
395 kSuggestedSaveNames[i].ensure_html_extension,
396 std::string());
397 EXPECT_EQ(kSuggestedSaveNames[i].expected_name, save_name.value()) <<
398 "Test case " << i;
399 }
400 }
401
402 static const FilePath::CharType* kTestDir = FILE_PATH_LITERAL("save_page");
403
404 // GetUrlToBeSaved method should return correct url to be saved.
405 TEST_F(SavePackageTest, TestGetUrlToBeSaved) {
406 FilePath file_name(FILE_PATH_LITERAL("a.htm"));
407 GURL url = URLRequestMockHTTPJob::GetMockUrl(
408 FilePath(kTestDir).Append(file_name));
409 NavigateAndCommit(url);
410 EXPECT_EQ(url, GetUrlToBeSaved());
411 }
412
413 // GetUrlToBeSaved method sould return actual url to be saved,
414 // instead of the displayed url used to view source of a page.
415 // Ex:GetUrlToBeSaved method should return http://www.google.com
416 // when user types view-source:http://www.google.com
417 TEST_F(SavePackageTest, TestGetUrlToBeSavedViewSource) {
418 FilePath file_name(FILE_PATH_LITERAL("a.htm"));
419 GURL view_source_url = URLRequestMockHTTPJob::GetMockViewSourceUrl(
420 FilePath(kTestDir).Append(file_name));
421 GURL actual_url = URLRequestMockHTTPJob::GetMockUrl(
422 FilePath(kTestDir).Append(file_name));
423 NavigateAndCommit(view_source_url);
424 EXPECT_EQ(actual_url, GetUrlToBeSaved());
425 EXPECT_EQ(view_source_url, contents()->GetURL());
426 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698