OLD | NEW |
| (Empty) |
1 // Copyright 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 <set> | |
6 #include <string> | |
7 #include <vector> | |
8 | |
9 #include "base/bind_helpers.h" | |
10 #include "base/file_util.h" | |
11 #include "base/files/file_path.h" | |
12 #include "base/files/scoped_temp_dir.h" | |
13 #include "base/memory/ref_counted.h" | |
14 #include "base/memory/scoped_vector.h" | |
15 #include "base/message_loop/message_loop.h" | |
16 #include "base/message_loop/message_loop_proxy.h" | |
17 #include "base/platform_file.h" | |
18 #include "base/run_loop.h" | |
19 #include "base/strings/stringprintf.h" | |
20 #include "base/time/time.h" | |
21 #include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h" | |
22 #include "chrome/browser/media_galleries/fileapi/media_path_filter.h" | |
23 #include "chrome/browser/media_galleries/fileapi/picasa/picasa_data_provider.h" | |
24 #include "chrome/browser/media_galleries/fileapi/picasa/picasa_file_util.h" | |
25 #include "chrome/common/media_galleries/picasa_types.h" | |
26 #include "chrome/common/media_galleries/pmp_constants.h" | |
27 #include "content/public/browser/browser_thread.h" | |
28 #include "content/public/test/test_browser_thread.h" | |
29 #include "testing/gtest/include/gtest/gtest.h" | |
30 #include "webkit/browser/fileapi/async_file_util_adapter.h" | |
31 #include "webkit/browser/fileapi/external_mount_points.h" | |
32 #include "webkit/browser/fileapi/file_system_context.h" | |
33 #include "webkit/browser/fileapi/file_system_file_util.h" | |
34 #include "webkit/browser/fileapi/file_system_operation_context.h" | |
35 #include "webkit/browser/fileapi/file_system_operation_runner.h" | |
36 #include "webkit/browser/fileapi/isolated_context.h" | |
37 #include "webkit/browser/fileapi/mock_file_system_options.h" | |
38 #include "webkit/browser/quota/mock_special_storage_policy.h" | |
39 #include "webkit/common/blob/shareable_file_reference.h" | |
40 | |
41 using fileapi::FileSystemFileUtil; | |
42 using fileapi::FileSystemOperationContext; | |
43 using fileapi::FileSystemOperation; | |
44 using fileapi::FileSystemURL; | |
45 | |
46 namespace picasa { | |
47 | |
48 namespace { | |
49 | |
50 base::Time::Exploded test_date_exploded = { 2013, 4, 0, 16, 0, 0, 0, 0 }; | |
51 | |
52 bool WriteJPEGHeader(const base::FilePath& path) { | |
53 const char kJpegHeader[] = "\xFF\xD8\xFF"; // Per HTML5 specification. | |
54 return file_util::WriteFile(path, kJpegHeader, arraysize(kJpegHeader)) != -1; | |
55 } | |
56 | |
57 class TestFolder { | |
58 public: | |
59 TestFolder(const std::string& name, const base::Time& timestamp, | |
60 const std::string& uid, unsigned int image_files, | |
61 unsigned int non_image_files) | |
62 : name_(name), | |
63 timestamp_(timestamp), | |
64 uid_(uid), | |
65 image_files_(image_files), | |
66 non_image_files_(non_image_files), | |
67 folder_info_("", base::Time(), "", base::FilePath()) { | |
68 } | |
69 | |
70 bool Init() { | |
71 if (!folder_dir_.CreateUniqueTempDir()) | |
72 return false; | |
73 | |
74 folder_info_ = AlbumInfo(name_, timestamp_, uid_, folder_dir_.path()); | |
75 | |
76 for (unsigned int i = 0; i < image_files_; ++i) { | |
77 std::string image_filename = base::StringPrintf("img%05d.jpg", i); | |
78 image_filenames_.insert(image_filename); | |
79 | |
80 base::FilePath path = folder_dir_.path().AppendASCII(image_filename); | |
81 | |
82 if (!WriteJPEGHeader(path)) | |
83 return false; | |
84 } | |
85 | |
86 for (unsigned int i = 0; i < non_image_files_; ++i) { | |
87 base::FilePath path = folder_dir_.path().AppendASCII( | |
88 base::StringPrintf("hello%05d.txt", i)); | |
89 if (file_util::WriteFile(path, NULL, 0) == -1) | |
90 return false; | |
91 } | |
92 | |
93 return true; | |
94 } | |
95 | |
96 double GetVariantTimestamp() const { | |
97 DCHECK(!folder_dir_.path().empty()); | |
98 base::Time variant_epoch = base::Time::FromLocalExploded( | |
99 picasa::kPmpVariantTimeEpoch); | |
100 | |
101 int64 microseconds_since_epoch = | |
102 (folder_info_.timestamp - variant_epoch).InMicroseconds(); | |
103 | |
104 return static_cast<double>(microseconds_since_epoch) / | |
105 base::Time::kMicrosecondsPerDay; | |
106 } | |
107 | |
108 const std::set<std::string>& image_filenames() const { | |
109 DCHECK(!folder_dir_.path().empty()); | |
110 return image_filenames_; | |
111 } | |
112 | |
113 const AlbumInfo& folder_info() const { | |
114 DCHECK(!folder_dir_.path().empty()); | |
115 return folder_info_; | |
116 } | |
117 | |
118 const base::Time& timestamp() const { | |
119 return timestamp_; | |
120 } | |
121 | |
122 private: | |
123 const std::string name_; | |
124 const base::Time timestamp_; | |
125 const std::string uid_; | |
126 unsigned int image_files_; | |
127 unsigned int non_image_files_; | |
128 | |
129 std::set<std::string> image_filenames_; | |
130 | |
131 base::ScopedTempDir folder_dir_; | |
132 AlbumInfo folder_info_; | |
133 }; | |
134 | |
135 void ReadDirectoryTestHelperCallback( | |
136 base::RunLoop* run_loop, | |
137 FileSystemOperation::FileEntryList* contents, | |
138 bool* completed, base::PlatformFileError error, | |
139 const FileSystemOperation::FileEntryList& file_list, | |
140 bool has_more) { | |
141 DCHECK(!*completed); | |
142 *completed = !has_more && error == base::PLATFORM_FILE_OK; | |
143 *contents = file_list; | |
144 run_loop->Quit(); | |
145 } | |
146 | |
147 void ReadDirectoryTestHelper(fileapi::FileSystemOperationRunner* runner, | |
148 const FileSystemURL& url, | |
149 FileSystemOperation::FileEntryList* contents, | |
150 bool* completed) { | |
151 DCHECK(contents); | |
152 DCHECK(completed); | |
153 base::RunLoop run_loop; | |
154 runner->ReadDirectory( | |
155 url, base::Bind(&ReadDirectoryTestHelperCallback, &run_loop, contents, | |
156 completed)); | |
157 run_loop.Run(); | |
158 } | |
159 | |
160 void SynchronouslyRunOnMediaTaskRunner(const base::Closure& closure) { | |
161 base::RunLoop loop; | |
162 chrome::MediaFileSystemBackend::MediaTaskRunner()->PostTaskAndReply( | |
163 FROM_HERE, | |
164 closure, | |
165 loop.QuitClosure()); | |
166 loop.Run(); | |
167 } | |
168 | |
169 void CreateSnapshotFileTestHelperCallback( | |
170 base::RunLoop* run_loop, | |
171 base::PlatformFileError* error, | |
172 base::FilePath* platform_path_result, | |
173 base::PlatformFileError result, | |
174 const base::PlatformFileInfo& file_info, | |
175 const base::FilePath& platform_path, | |
176 const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref) { | |
177 DCHECK(run_loop); | |
178 DCHECK(error); | |
179 DCHECK(platform_path_result); | |
180 | |
181 *error = result; | |
182 *platform_path_result = platform_path; | |
183 run_loop->Quit(); | |
184 } | |
185 | |
186 } // namespace | |
187 | |
188 class TestPicasaFileUtil : public PicasaFileUtil { | |
189 public: | |
190 TestPicasaFileUtil(chrome::MediaPathFilter* media_path_filter, | |
191 PicasaDataProvider* data_provider) | |
192 : PicasaFileUtil(media_path_filter), | |
193 data_provider_(data_provider) { | |
194 } | |
195 virtual ~TestPicasaFileUtil() {} | |
196 private: | |
197 virtual PicasaDataProvider* GetDataProvider() OVERRIDE { | |
198 return data_provider_; | |
199 } | |
200 | |
201 PicasaDataProvider* data_provider_; | |
202 }; | |
203 | |
204 class TestMediaFileSystemBackend | |
205 : public chrome::MediaFileSystemBackend { | |
206 public: | |
207 TestMediaFileSystemBackend(const base::FilePath& profile_path, | |
208 PicasaFileUtil* picasa_file_util) | |
209 : chrome::MediaFileSystemBackend( | |
210 profile_path, | |
211 chrome::MediaFileSystemBackend::MediaTaskRunner().get()), | |
212 test_file_util_(picasa_file_util) {} | |
213 | |
214 virtual fileapi::AsyncFileUtil* | |
215 GetAsyncFileUtil(fileapi::FileSystemType type) OVERRIDE { | |
216 if (type != fileapi::kFileSystemTypePicasa) | |
217 return NULL; | |
218 | |
219 return test_file_util_.get(); | |
220 } | |
221 | |
222 private: | |
223 scoped_ptr<fileapi::AsyncFileUtil> test_file_util_; | |
224 }; | |
225 | |
226 class PicasaFileUtilTest : public testing::Test { | |
227 public: | |
228 PicasaFileUtilTest() | |
229 : io_thread_(content::BrowserThread::IO, &message_loop_) { | |
230 } | |
231 virtual ~PicasaFileUtilTest() {} | |
232 | |
233 virtual void SetUp() OVERRIDE { | |
234 ASSERT_TRUE(profile_dir_.CreateUniqueTempDir()); | |
235 | |
236 scoped_refptr<quota::SpecialStoragePolicy> storage_policy = | |
237 new quota::MockSpecialStoragePolicy(); | |
238 | |
239 SynchronouslyRunOnMediaTaskRunner(base::Bind( | |
240 &PicasaFileUtilTest::SetUpOnMediaTaskRunner, base::Unretained(this))); | |
241 | |
242 media_path_filter_.reset(new chrome::MediaPathFilter()); | |
243 | |
244 ScopedVector<fileapi::FileSystemBackend> additional_providers; | |
245 additional_providers.push_back(new TestMediaFileSystemBackend( | |
246 profile_dir_.path(), | |
247 new TestPicasaFileUtil(media_path_filter_.get(), | |
248 picasa_data_provider_.get()))); | |
249 | |
250 file_system_context_ = new fileapi::FileSystemContext( | |
251 base::MessageLoopProxy::current().get(), | |
252 base::MessageLoopProxy::current().get(), | |
253 fileapi::ExternalMountPoints::CreateRefCounted().get(), | |
254 storage_policy.get(), | |
255 NULL, | |
256 additional_providers.Pass(), | |
257 profile_dir_.path(), | |
258 fileapi::CreateAllowFileAccessOptions()); | |
259 } | |
260 | |
261 virtual void TearDown() OVERRIDE { | |
262 SynchronouslyRunOnMediaTaskRunner( | |
263 base::Bind(&PicasaFileUtilTest::TearDownOnMediaTaskRunner, | |
264 base::Unretained(this))); | |
265 } | |
266 | |
267 protected: | |
268 void SetUpOnMediaTaskRunner() { | |
269 picasa_data_provider_.reset(new PicasaDataProvider(base::FilePath())); | |
270 } | |
271 | |
272 void TearDownOnMediaTaskRunner() { | |
273 picasa_data_provider_.reset(); | |
274 } | |
275 | |
276 // |test_folders| must be in alphabetical order for easy verification | |
277 void SetupFolders(ScopedVector<TestFolder>* test_folders, | |
278 const std::vector<AlbumInfo>& albums, | |
279 const AlbumImagesMap& albums_images) { | |
280 std::vector<AlbumInfo> folders; | |
281 for (ScopedVector<TestFolder>::iterator it = test_folders->begin(); | |
282 it != test_folders->end(); ++it) { | |
283 TestFolder* test_folder = *it; | |
284 ASSERT_TRUE(test_folder->Init()); | |
285 folders.push_back(test_folder->folder_info()); | |
286 } | |
287 | |
288 PicasaDataProvider::UniquifyNames(albums, | |
289 &picasa_data_provider_->album_map_); | |
290 PicasaDataProvider::UniquifyNames(folders, | |
291 &picasa_data_provider_->folder_map_); | |
292 picasa_data_provider_->albums_images_ = albums_images; | |
293 picasa_data_provider_->state_ = | |
294 PicasaDataProvider::ALBUMS_IMAGES_FRESH_STATE; | |
295 } | |
296 | |
297 void VerifyFolderDirectoryList(const ScopedVector<TestFolder>& test_folders) { | |
298 FileSystemOperation::FileEntryList contents; | |
299 FileSystemURL url = CreateURL(kPicasaDirFolders); | |
300 bool completed = false; | |
301 ReadDirectoryTestHelper(operation_runner(), url, &contents, &completed); | |
302 | |
303 ASSERT_TRUE(completed); | |
304 ASSERT_EQ(test_folders.size(), contents.size()); | |
305 | |
306 for (size_t i = 0; i < contents.size(); ++i) { | |
307 EXPECT_TRUE(contents[i].is_directory); | |
308 | |
309 // Because the timestamp is written out as a floating point Microsoft | |
310 // variant time, we only expect it to be accurate to within a second. | |
311 base::TimeDelta delta = test_folders[i]->folder_info().timestamp - | |
312 contents[i].last_modified_time; | |
313 EXPECT_LT(delta, base::TimeDelta::FromSeconds(1)); | |
314 | |
315 FileSystemOperation::FileEntryList folder_contents; | |
316 FileSystemURL folder_url = CreateURL( | |
317 std::string(kPicasaDirFolders) + "/" + | |
318 base::FilePath(contents[i].name).AsUTF8Unsafe()); | |
319 bool folder_read_completed = false; | |
320 ReadDirectoryTestHelper(operation_runner(), folder_url, &folder_contents, | |
321 &folder_read_completed); | |
322 | |
323 EXPECT_TRUE(folder_read_completed); | |
324 | |
325 const std::set<std::string>& image_filenames = | |
326 test_folders[i]->image_filenames(); | |
327 | |
328 EXPECT_EQ(image_filenames.size(), folder_contents.size()); | |
329 | |
330 for (FileSystemOperation::FileEntryList::const_iterator file_it = | |
331 folder_contents.begin(); file_it != folder_contents.end(); | |
332 ++file_it) { | |
333 EXPECT_EQ(1u, image_filenames.count( | |
334 base::FilePath(file_it->name).AsUTF8Unsafe())); | |
335 } | |
336 } | |
337 } | |
338 | |
339 std::string DateToPathString(const base::Time& time) { | |
340 return PicasaDataProvider::DateToPathString(time); | |
341 } | |
342 | |
343 void TestNonexistentDirectory(const std::string& path) { | |
344 FileSystemOperation::FileEntryList contents; | |
345 FileSystemURL url = CreateURL(path); | |
346 bool completed = false; | |
347 ReadDirectoryTestHelper(operation_runner(), url, &contents, &completed); | |
348 | |
349 ASSERT_FALSE(completed); | |
350 } | |
351 | |
352 void TestEmptyDirectory(const std::string& path) { | |
353 FileSystemOperation::FileEntryList contents; | |
354 FileSystemURL url = CreateURL(path); | |
355 bool completed = false; | |
356 ReadDirectoryTestHelper(operation_runner(), url, &contents, &completed); | |
357 | |
358 ASSERT_TRUE(completed); | |
359 EXPECT_EQ(0u, contents.size()); | |
360 } | |
361 | |
362 FileSystemURL CreateURL(const std::string& virtual_path) const { | |
363 return file_system_context_->CreateCrackedFileSystemURL( | |
364 GURL("http://www.example.com"), fileapi::kFileSystemTypePicasa, | |
365 base::FilePath::FromUTF8Unsafe(virtual_path)); | |
366 } | |
367 | |
368 fileapi::FileSystemOperationRunner* operation_runner() const { | |
369 return file_system_context_->operation_runner(); | |
370 } | |
371 | |
372 scoped_refptr<fileapi::FileSystemContext> file_system_context() const { | |
373 return file_system_context_; | |
374 } | |
375 | |
376 private: | |
377 base::MessageLoop message_loop_; | |
378 content::TestBrowserThread io_thread_; | |
379 | |
380 base::ScopedTempDir profile_dir_; | |
381 | |
382 scoped_refptr<fileapi::FileSystemContext> file_system_context_; | |
383 scoped_ptr<PicasaDataProvider> picasa_data_provider_; | |
384 scoped_ptr<chrome::MediaPathFilter> media_path_filter_; | |
385 | |
386 DISALLOW_COPY_AND_ASSIGN(PicasaFileUtilTest); | |
387 }; | |
388 | |
389 TEST_F(PicasaFileUtilTest, DateFormat) { | |
390 base::Time::Exploded exploded_shortmonth = { 2013, 4, 0, 16, 0, 0, 0, 0 }; | |
391 base::Time shortmonth = base::Time::FromLocalExploded(exploded_shortmonth); | |
392 | |
393 base::Time::Exploded exploded_shortday = { 2013, 11, 0, 3, 0, 0, 0, 0 }; | |
394 base::Time shortday = base::Time::FromLocalExploded(exploded_shortday); | |
395 | |
396 EXPECT_EQ("2013-04-16", DateToPathString(shortmonth)); | |
397 EXPECT_EQ("2013-11-03", DateToPathString(shortday)); | |
398 } | |
399 | |
400 TEST_F(PicasaFileUtilTest, NameDeduplication) { | |
401 ScopedVector<TestFolder> test_folders; | |
402 std::vector<std::string> expected_names; | |
403 | |
404 base::Time test_date = base::Time::FromLocalExploded(test_date_exploded); | |
405 base::Time test_date_2 = test_date - base::TimeDelta::FromDays(1); | |
406 | |
407 std::string test_date_string = DateToPathString(test_date); | |
408 std::string test_date_2_string = DateToPathString(test_date_2); | |
409 | |
410 test_folders.push_back( | |
411 new TestFolder("diff_date", test_date_2, "uuid3", 0, 0)); | |
412 expected_names.push_back("diff_date " + test_date_2_string); | |
413 | |
414 test_folders.push_back( | |
415 new TestFolder("diff_date", test_date, "uuid2", 0, 0)); | |
416 expected_names.push_back("diff_date " + test_date_string); | |
417 | |
418 test_folders.push_back( | |
419 new TestFolder("duplicate", test_date, "uuid4", 0, 0)); | |
420 expected_names.push_back("duplicate " + test_date_string + " (1)"); | |
421 | |
422 test_folders.push_back( | |
423 new TestFolder("duplicate", test_date, "uuid5", 0, 0)); | |
424 expected_names.push_back("duplicate " + test_date_string + " (2)"); | |
425 | |
426 test_folders.push_back( | |
427 new TestFolder("unique_name", test_date, "uuid1", 0, 0)); | |
428 expected_names.push_back("unique_name " + test_date_string); | |
429 | |
430 SetupFolders(&test_folders, std::vector<AlbumInfo>(), AlbumImagesMap()); | |
431 | |
432 FileSystemOperation::FileEntryList contents; | |
433 FileSystemURL url = CreateURL(kPicasaDirFolders); | |
434 bool completed = false; | |
435 ReadDirectoryTestHelper(operation_runner(), url, &contents, &completed); | |
436 | |
437 ASSERT_TRUE(completed); | |
438 ASSERT_EQ(expected_names.size(), contents.size()); | |
439 for (size_t i = 0; i < contents.size(); ++i) { | |
440 EXPECT_EQ(expected_names[i], | |
441 base::FilePath(contents[i].name).AsUTF8Unsafe()); | |
442 EXPECT_EQ(test_folders[i]->timestamp(), contents[i].last_modified_time); | |
443 EXPECT_TRUE(contents[i].is_directory); | |
444 } | |
445 } | |
446 | |
447 TEST_F(PicasaFileUtilTest, RootFolders) { | |
448 ScopedVector<TestFolder> empty_folders_list; | |
449 SetupFolders(&empty_folders_list, std::vector<AlbumInfo>(), AlbumImagesMap()); | |
450 | |
451 FileSystemOperation::FileEntryList contents; | |
452 FileSystemURL url = CreateURL(""); | |
453 bool completed = false; | |
454 ReadDirectoryTestHelper(operation_runner(), url, &contents, &completed); | |
455 | |
456 ASSERT_TRUE(completed); | |
457 ASSERT_EQ(2u, contents.size()); | |
458 | |
459 EXPECT_TRUE(contents.front().is_directory); | |
460 EXPECT_TRUE(contents.back().is_directory); | |
461 | |
462 EXPECT_EQ(0, contents.front().size); | |
463 EXPECT_EQ(0, contents.back().size); | |
464 | |
465 EXPECT_EQ(FILE_PATH_LITERAL("albums"), contents.front().name); | |
466 EXPECT_EQ(FILE_PATH_LITERAL("folders"), contents.back().name); | |
467 } | |
468 | |
469 TEST_F(PicasaFileUtilTest, NonexistentFolder) { | |
470 ScopedVector<TestFolder> empty_folders_list; | |
471 SetupFolders(&empty_folders_list, std::vector<AlbumInfo>(), AlbumImagesMap()); | |
472 | |
473 TestNonexistentDirectory(std::string(kPicasaDirFolders) + "/foo"); | |
474 TestNonexistentDirectory(std::string(kPicasaDirFolders) + "/foo/bar"); | |
475 TestNonexistentDirectory(std::string(kPicasaDirFolders) + "/foo/bar/baz"); | |
476 } | |
477 | |
478 TEST_F(PicasaFileUtilTest, FolderContentsTrivial) { | |
479 ScopedVector<TestFolder> test_folders; | |
480 base::Time test_date = base::Time::FromLocalExploded(test_date_exploded); | |
481 | |
482 test_folders.push_back( | |
483 new TestFolder("folder-1-empty", test_date, "uid-empty", 0, 0)); | |
484 test_folders.push_back( | |
485 new TestFolder("folder-2-images", test_date, "uid-images", 5, 0)); | |
486 test_folders.push_back( | |
487 new TestFolder("folder-3-nonimages", test_date, "uid-nonimages", 0, 5)); | |
488 test_folders.push_back( | |
489 new TestFolder("folder-4-both", test_date, "uid-both", 5, 5)); | |
490 | |
491 SetupFolders(&test_folders, std::vector<AlbumInfo>(), AlbumImagesMap()); | |
492 VerifyFolderDirectoryList(test_folders); | |
493 } | |
494 | |
495 TEST_F(PicasaFileUtilTest, FolderWithManyFiles) { | |
496 ScopedVector<TestFolder> test_folders; | |
497 base::Time test_date = base::Time::FromLocalExploded(test_date_exploded); | |
498 | |
499 test_folders.push_back( | |
500 new TestFolder("folder-many-files", test_date, "uid-both", 500, 500)); | |
501 | |
502 SetupFolders(&test_folders, std::vector<AlbumInfo>(), AlbumImagesMap()); | |
503 VerifyFolderDirectoryList(test_folders); | |
504 } | |
505 | |
506 TEST_F(PicasaFileUtilTest, ManyFolders) { | |
507 ScopedVector<TestFolder> test_folders; | |
508 base::Time test_date = base::Time::FromLocalExploded(test_date_exploded); | |
509 | |
510 // TODO(tommycli): Turn number of test folders back up to 50 (or more) once | |
511 // https://codereview.chromium.org/15479003/ lands. | |
512 for (unsigned int i = 0; i < 25; ++i) { | |
513 base::Time date = test_date - base::TimeDelta::FromDays(i); | |
514 | |
515 test_folders.push_back( | |
516 new TestFolder(base::StringPrintf("folder-%05d", i), | |
517 date, | |
518 base::StringPrintf("uid%05d", i), i % 5, i % 3)); | |
519 } | |
520 | |
521 SetupFolders(&test_folders, std::vector<AlbumInfo>(), AlbumImagesMap()); | |
522 VerifyFolderDirectoryList(test_folders); | |
523 } | |
524 | |
525 TEST_F(PicasaFileUtilTest, AlbumExistence) { | |
526 ScopedVector<TestFolder> test_folders; | |
527 base::Time test_date = base::Time::FromLocalExploded(test_date_exploded); | |
528 | |
529 std::vector<AlbumInfo> albums; | |
530 AlbumInfo info; | |
531 info.name = "albumname"; | |
532 info.uid = "albumuid"; | |
533 info.timestamp = test_date; | |
534 albums.push_back(info); | |
535 | |
536 AlbumImagesMap albums_images; | |
537 albums_images[info.uid] = AlbumImages(); | |
538 | |
539 SetupFolders(&test_folders, albums, albums_images); | |
540 | |
541 TestEmptyDirectory(std::string(kPicasaDirAlbums) + "/albumname 2013-04-16"); | |
542 TestNonexistentDirectory(std::string(kPicasaDirAlbums) + | |
543 "/albumname 2013-04-16/toodeep"); | |
544 TestNonexistentDirectory(std::string(kPicasaDirAlbums) + "/wrongname"); | |
545 } | |
546 | |
547 TEST_F(PicasaFileUtilTest, AlbumContents) { | |
548 ScopedVector<TestFolder> test_folders; | |
549 base::Time test_date = base::Time::FromLocalExploded(test_date_exploded); | |
550 | |
551 std::vector<AlbumInfo> albums; | |
552 AlbumInfo info; | |
553 info.name = "albumname"; | |
554 info.uid = "albumuid"; | |
555 info.timestamp = test_date; | |
556 albums.push_back(info); | |
557 | |
558 base::ScopedTempDir temp_dir; | |
559 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); | |
560 | |
561 base::FilePath image_path = temp_dir.path().AppendASCII("img.jpg"); | |
562 ASSERT_TRUE(WriteJPEGHeader(image_path)); | |
563 | |
564 AlbumImagesMap albums_images; | |
565 albums_images[info.uid] = AlbumImages(); | |
566 albums_images[info.uid]["mapped_name.jpg"] = image_path; | |
567 | |
568 SetupFolders(&test_folders, albums, albums_images); | |
569 | |
570 FileSystemOperation::FileEntryList contents; | |
571 FileSystemURL url = | |
572 CreateURL(std::string(kPicasaDirAlbums) + "/albumname 2013-04-16"); | |
573 bool completed = false; | |
574 ReadDirectoryTestHelper(operation_runner(), url, &contents, &completed); | |
575 | |
576 ASSERT_TRUE(completed); | |
577 EXPECT_EQ(1u, contents.size()); | |
578 EXPECT_EQ("mapped_name.jpg", | |
579 base::FilePath(contents.begin()->name).AsUTF8Unsafe()); | |
580 EXPECT_FALSE(contents.begin()->is_directory); | |
581 | |
582 // Create a snapshot file to verify the file path. | |
583 base::RunLoop loop; | |
584 base::PlatformFileError error; | |
585 base::FilePath platform_path_result; | |
586 fileapi::FileSystemOperationRunner::SnapshotFileCallback snapshot_callback = | |
587 base::Bind(&CreateSnapshotFileTestHelperCallback, | |
588 &loop, | |
589 &error, | |
590 &platform_path_result); | |
591 operation_runner()->CreateSnapshotFile( | |
592 CreateURL(std::string(kPicasaDirAlbums) + | |
593 "/albumname 2013-04-16/mapped_name.jpg"), | |
594 snapshot_callback); | |
595 loop.Run(); | |
596 EXPECT_EQ(base::PLATFORM_FILE_OK, error); | |
597 EXPECT_EQ(image_path, platform_path_result); | |
598 } | |
599 | |
600 } // namespace picasa | |
OLD | NEW |