190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// found in the LICENSE file.
490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include <set>
690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include <string>
7eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <vector>
890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
99ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/bind_helpers.h"
1058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/files/file_path.h"
111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h"
1290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/files/scoped_temp_dir.h"
1358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/memory/ref_counted.h"
1490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/memory/scoped_vector.h"
15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/message_loop/message_loop.h"
16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/message_loop/message_loop_proxy.h"
17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/run_loop.h"
18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h"
2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/media_galleries/fileapi/media_path_filter.h"
2258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/media_galleries/fileapi/picasa_data_provider.h"
2358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/media_galleries/fileapi/picasa_file_util.h"
24effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "chrome/browser/media_galleries/imported_media_gallery_registry.h"
25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/common/media_galleries/picasa_types.h"
26eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/common/media_galleries/pmp_constants.h"
279ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "content/public/browser/browser_thread.h"
285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "content/public/test/mock_special_storage_policy.h"
29868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/public/test/test_browser_thread.h"
304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/test/test_file_system_options.h"
311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/async_file_util.h"
321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/external_mount_points.h"
331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_context.h"
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_operation_context.h"
351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_operation_runner.h"
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/isolated_context.h"
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/common/blob/shareable_file_reference.h"
3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::FileSystemOperationContext;
4103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::FileSystemOperation;
4203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::FileSystemURL;
4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace picasa {
4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace {
4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)base::Time::Exploded test_date_exploded = { 2013, 4, 0, 16, 0, 0, 0, 0 };
4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool WriteJPEGHeader(const base::FilePath& path) {
5158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const char kJpegHeader[] = "\xFF\xD8\xFF";  // Per HTML5 specification.
52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return base::WriteFile(path, kJpegHeader, arraysize(kJpegHeader)) != -1;
5358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
5458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class TestFolder {
5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public:
5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  TestFolder(const std::string& name, const base::Time& timestamp,
5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)             const std::string& uid, unsigned int image_files,
5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)             unsigned int non_image_files)
6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      : name_(name),
6190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        timestamp_(timestamp),
6290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        uid_(uid),
6390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        image_files_(image_files),
6490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        non_image_files_(non_image_files),
6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        folder_info_("", base::Time(), "", base::FilePath()) {
6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
6890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  bool Init() {
6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (!folder_dir_.CreateUniqueTempDir())
7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return false;
7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    folder_info_ = AlbumInfo(name_, timestamp_, uid_, folder_dir_.path());
7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
7490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    for (unsigned int i = 0; i < image_files_; ++i) {
7590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      std::string image_filename = base::StringPrintf("img%05d.jpg", i);
7690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      image_filenames_.insert(image_filename);
7790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::FilePath path = folder_dir_.path().AppendASCII(image_filename);
7990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
8058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      if (!WriteJPEGHeader(path))
8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        return false;
8290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
8390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    for (unsigned int i = 0; i < non_image_files_; ++i) {
8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::FilePath path = folder_dir_.path().AppendASCII(
8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          base::StringPrintf("hello%05d.txt", i));
87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      if (base::WriteFile(path, NULL, 0) == -1)
8890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        return false;
8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return true;
9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  double GetVariantTimestamp() const {
9590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    DCHECK(!folder_dir_.path().empty());
9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::Time variant_epoch = base::Time::FromLocalExploded(
97eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        picasa::kPmpVariantTimeEpoch);
9890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
9990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    int64 microseconds_since_epoch =
10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        (folder_info_.timestamp - variant_epoch).InMicroseconds();
10190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return static_cast<double>(microseconds_since_epoch) /
10390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                               base::Time::kMicrosecondsPerDay;
10490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
10590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const std::set<std::string>& image_filenames() const {
10790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    DCHECK(!folder_dir_.path().empty());
10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return image_filenames_;
10990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
11090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
11190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const AlbumInfo& folder_info() const {
11290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    DCHECK(!folder_dir_.path().empty());
11390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return folder_info_;
11490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1169ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  const base::Time& timestamp() const {
1179ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch    return timestamp_;
1189ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  }
1199ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch
12090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) private:
12190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const std::string name_;
12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const base::Time timestamp_;
12390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const std::string uid_;
12490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  unsigned int image_files_;
12590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  unsigned int non_image_files_;
12690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
12790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::set<std::string> image_filenames_;
12890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
12990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::ScopedTempDir folder_dir_;
13090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  AlbumInfo folder_info_;
13190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)};
13290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1339ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdochvoid ReadDirectoryTestHelperCallback(
1349ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch    base::RunLoop* run_loop,
1359ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch    FileSystemOperation::FileEntryList* contents,
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bool* completed, base::File::Error error,
1379ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch    const FileSystemOperation::FileEntryList& file_list,
1389ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch    bool has_more) {
1399ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  DCHECK(!*completed);
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  *completed = !has_more && error == base::File::FILE_OK;
1419ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  *contents = file_list;
1429ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  run_loop->Quit();
1439ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch}
1449ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch
14503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void ReadDirectoryTestHelper(storage::FileSystemOperationRunner* runner,
1469ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch                             const FileSystemURL& url,
1479ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch                             FileSystemOperation::FileEntryList* contents,
1489ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch                             bool* completed) {
1499ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  DCHECK(contents);
1509ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  DCHECK(completed);
1519ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  base::RunLoop run_loop;
1529ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  runner->ReadDirectory(
1539ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch      url, base::Bind(&ReadDirectoryTestHelperCallback, &run_loop, contents,
1549ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch                      completed));
1559ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  run_loop.Run();
1569ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch}
1579ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch
15858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void SynchronouslyRunOnMediaTaskRunner(const base::Closure& closure) {
15958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  base::RunLoop loop;
160d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  MediaFileSystemBackend::MediaTaskRunner()->PostTaskAndReply(
16158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      FROM_HERE,
16258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      closure,
16358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      loop.QuitClosure());
16458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  loop.Run();
16558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
1667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
16758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void CreateSnapshotFileTestHelperCallback(
16858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    base::RunLoop* run_loop,
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::File::Error* error,
17058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    base::FilePath* platform_path_result,
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::File::Error result,
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::File::Info& file_info,
17358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const base::FilePath& platform_path,
17403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const scoped_refptr<storage::ShareableFileReference>& file_ref) {
17558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(run_loop);
17658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(error);
17758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(platform_path_result);
17858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
17958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  *error = result;
18058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  *platform_path_result = platform_path;
18158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  run_loop->Quit();
18258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
1837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
18458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}  // namespace
18590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
18690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class TestPicasaFileUtil : public PicasaFileUtil {
18790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public:
188d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  TestPicasaFileUtil(MediaPathFilter* media_path_filter,
189bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                     PicasaDataProvider* data_provider)
190bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      : PicasaFileUtil(media_path_filter),
191bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch        data_provider_(data_provider) {
19290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
19390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual ~TestPicasaFileUtil() {}
19490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) private:
1957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual PicasaDataProvider* GetDataProvider() OVERRIDE {
196eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return data_provider_;
19790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
19890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
199eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  PicasaDataProvider* data_provider_;
20090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)};
20190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
202d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)class TestMediaFileSystemBackend : public MediaFileSystemBackend {
20390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public:
2047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  TestMediaFileSystemBackend(const base::FilePath& profile_path,
2059ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch                             PicasaFileUtil* picasa_file_util)
206d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      : MediaFileSystemBackend(profile_path,
207d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                               MediaFileSystemBackend::MediaTaskRunner().get()),
2087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        test_file_util_(picasa_file_util) {}
20990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
21003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  virtual storage::AsyncFileUtil* GetAsyncFileUtil(
21103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::FileSystemType type) OVERRIDE {
21203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    if (type != storage::kFileSystemTypePicasa)
21390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return NULL;
21490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
21590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return test_file_util_.get();
21690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
21790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
21890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) private:
21903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_ptr<storage::AsyncFileUtil> test_file_util_;
22090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)};
22190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
22290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class PicasaFileUtilTest : public testing::Test {
22390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public:
224868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  PicasaFileUtilTest()
225868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      : io_thread_(content::BrowserThread::IO, &message_loop_) {
226868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
22790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual ~PicasaFileUtilTest() {}
22890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
22990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual void SetUp() OVERRIDE {
23090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    ASSERT_TRUE(profile_dir_.CreateUniqueTempDir());
231effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    ImportedMediaGalleryRegistry::GetInstance()->Initialize();
23290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
23303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    scoped_refptr<storage::SpecialStoragePolicy> storage_policy =
2345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        new content::MockSpecialStoragePolicy();
23590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
23658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    SynchronouslyRunOnMediaTaskRunner(base::Bind(
23758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        &PicasaFileUtilTest::SetUpOnMediaTaskRunner, base::Unretained(this)));
23858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
239d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    media_path_filter_.reset(new MediaPathFilter());
240eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
24103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    ScopedVector<storage::FileSystemBackend> additional_providers;
2427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    additional_providers.push_back(new TestMediaFileSystemBackend(
243868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        profile_dir_.path(),
244bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch        new TestPicasaFileUtil(media_path_filter_.get(),
245bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                               picasa_data_provider_.get())));
24690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
24703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    file_system_context_ = new storage::FileSystemContext(
248a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        base::MessageLoopProxy::current().get(),
249a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        base::MessageLoopProxy::current().get(),
25003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        storage::ExternalMountPoints::CreateRefCounted().get(),
251868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        storage_policy.get(),
25290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        NULL,
25390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        additional_providers.Pass(),
25403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        std::vector<storage::URLRequestAutoMountHandler>(),
25590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        profile_dir_.path(),
2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        content::CreateAllowFileAccessOptions());
25790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
25890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
25958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void TearDown() OVERRIDE {
26058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    SynchronouslyRunOnMediaTaskRunner(
26158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        base::Bind(&PicasaFileUtilTest::TearDownOnMediaTaskRunner,
26258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                   base::Unretained(this)));
26358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
26458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
26590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) protected:
26658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void SetUpOnMediaTaskRunner() {
26758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    picasa_data_provider_.reset(new PicasaDataProvider(base::FilePath()));
26858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
26958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
27058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void TearDownOnMediaTaskRunner() {
27158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    picasa_data_provider_.reset();
27258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
27358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
27490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // |test_folders| must be in alphabetical order for easy verification
27558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void SetupFolders(ScopedVector<TestFolder>* test_folders,
27658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                    const std::vector<AlbumInfo>& albums,
27758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                    const AlbumImagesMap& albums_images) {
278eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    std::vector<AlbumInfo> folders;
27990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    for (ScopedVector<TestFolder>::iterator it = test_folders->begin();
28090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        it != test_folders->end(); ++it) {
28190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      TestFolder* test_folder = *it;
28290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      ASSERT_TRUE(test_folder->Init());
283eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      folders.push_back(test_folder->folder_info());
28490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
28558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
28658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    PicasaDataProvider::UniquifyNames(albums,
28758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                      &picasa_data_provider_->album_map_);
28858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    PicasaDataProvider::UniquifyNames(folders,
28958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                      &picasa_data_provider_->folder_map_);
29058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    picasa_data_provider_->albums_images_ = albums_images;
29158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    picasa_data_provider_->state_ =
29258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        PicasaDataProvider::ALBUMS_IMAGES_FRESH_STATE;
29390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
29490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
29590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void VerifyFolderDirectoryList(const ScopedVector<TestFolder>& test_folders) {
29690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    FileSystemOperation::FileEntryList contents;
29790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    FileSystemURL url = CreateURL(kPicasaDirFolders);
29890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    bool completed = false;
2999ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch    ReadDirectoryTestHelper(operation_runner(), url, &contents, &completed);
30090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
30190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    ASSERT_TRUE(completed);
30290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    ASSERT_EQ(test_folders.size(), contents.size());
30390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
30490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    for (size_t i = 0; i < contents.size(); ++i) {
30590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      EXPECT_TRUE(contents[i].is_directory);
30690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
30790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      // Because the timestamp is written out as a floating point Microsoft
30890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      // variant time, we only expect it to be accurate to within a second.
30990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::TimeDelta delta = test_folders[i]->folder_info().timestamp -
31090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                              contents[i].last_modified_time;
31190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      EXPECT_LT(delta, base::TimeDelta::FromSeconds(1));
31290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
31390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      FileSystemOperation::FileEntryList folder_contents;
31490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      FileSystemURL folder_url = CreateURL(
31590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          std::string(kPicasaDirFolders) + "/" +
31690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          base::FilePath(contents[i].name).AsUTF8Unsafe());
31790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      bool folder_read_completed = false;
3189ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch      ReadDirectoryTestHelper(operation_runner(), folder_url, &folder_contents,
3199ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch                              &folder_read_completed);
32090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
32190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      EXPECT_TRUE(folder_read_completed);
32290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
32390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      const std::set<std::string>& image_filenames =
32490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          test_folders[i]->image_filenames();
32590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
32690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      EXPECT_EQ(image_filenames.size(), folder_contents.size());
32790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
32890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      for (FileSystemOperation::FileEntryList::const_iterator file_it =
32990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)               folder_contents.begin(); file_it != folder_contents.end();
33090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)           ++file_it) {
33190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        EXPECT_EQ(1u, image_filenames.count(
33290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)            base::FilePath(file_it->name).AsUTF8Unsafe()));
33390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      }
33490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
33590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
33690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
33790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::string DateToPathString(const base::Time& time) {
33890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return PicasaDataProvider::DateToPathString(time);
33990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
34090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
34158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void TestNonexistentDirectory(const std::string& path) {
34290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    FileSystemOperation::FileEntryList contents;
34358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    FileSystemURL url = CreateURL(path);
34490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    bool completed = false;
3459ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch    ReadDirectoryTestHelper(operation_runner(), url, &contents, &completed);
34690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
34790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    ASSERT_FALSE(completed);
34890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
34990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
35058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void TestEmptyDirectory(const std::string& path) {
35158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    FileSystemOperation::FileEntryList contents;
35258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    FileSystemURL url = CreateURL(path);
35358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    bool completed = false;
35458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    ReadDirectoryTestHelper(operation_runner(), url, &contents, &completed);
35558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
35658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    ASSERT_TRUE(completed);
35758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EXPECT_EQ(0u, contents.size());
35858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
35958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
360effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  FileSystemURL CreateURL(const std::string& path) const {
361effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    base::FilePath virtual_path =
362effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        ImportedMediaGalleryRegistry::GetInstance()->ImportedRoot();
363effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    virtual_path = virtual_path.AppendASCII("picasa");
364effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    virtual_path = virtual_path.AppendASCII(path);
36590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return file_system_context_->CreateCrackedFileSystemURL(
36603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        GURL("http://www.example.com"),
36703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        storage::kFileSystemTypePicasa,
368effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        virtual_path);
36990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
37090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
37103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  storage::FileSystemOperationRunner* operation_runner() const {
372868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return file_system_context_->operation_runner();
37390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
37490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
37503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_refptr<storage::FileSystemContext> file_system_context() const {
37690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return file_system_context_;
37790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
37890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
37990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) private:
38090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop message_loop_;
381868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  content::TestBrowserThread io_thread_;
38290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
38390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::ScopedTempDir profile_dir_;
38490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
38503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_refptr<storage::FileSystemContext> file_system_context_;
38658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scoped_ptr<PicasaDataProvider> picasa_data_provider_;
387d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  scoped_ptr<MediaPathFilter> media_path_filter_;
38890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
38990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(PicasaFileUtilTest);
39090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)};
39190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
39290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)TEST_F(PicasaFileUtilTest, DateFormat) {
39390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::Time::Exploded exploded_shortmonth = { 2013, 4, 0, 16, 0, 0, 0, 0 };
39490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::Time shortmonth = base::Time::FromLocalExploded(exploded_shortmonth);
39590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
39690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::Time::Exploded exploded_shortday = { 2013, 11, 0, 3, 0, 0, 0, 0 };
39790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::Time shortday = base::Time::FromLocalExploded(exploded_shortday);
39890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
39990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ("2013-04-16", DateToPathString(shortmonth));
40090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ("2013-11-03", DateToPathString(shortday));
40190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
40290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
40390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)TEST_F(PicasaFileUtilTest, NameDeduplication) {
4049ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  ScopedVector<TestFolder> test_folders;
40590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::vector<std::string> expected_names;
40690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
40790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::Time test_date = base::Time::FromLocalExploded(test_date_exploded);
40890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::Time test_date_2 = test_date - base::TimeDelta::FromDays(1);
40990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
41090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::string test_date_string = DateToPathString(test_date);
41190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::string test_date_2_string = DateToPathString(test_date_2);
41290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4139ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  test_folders.push_back(
4149ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch      new TestFolder("diff_date", test_date_2, "uuid3", 0, 0));
41590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  expected_names.push_back("diff_date " + test_date_2_string);
41690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4179ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  test_folders.push_back(
4189ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch      new TestFolder("diff_date", test_date, "uuid2", 0, 0));
41990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  expected_names.push_back("diff_date " + test_date_string);
42090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4219ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  test_folders.push_back(
4229ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch      new TestFolder("duplicate", test_date, "uuid4", 0, 0));
42390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  expected_names.push_back("duplicate " + test_date_string + " (1)");
42490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4259ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  test_folders.push_back(
4269ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch      new TestFolder("duplicate", test_date, "uuid5", 0, 0));
42790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  expected_names.push_back("duplicate " + test_date_string + " (2)");
42890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4299ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  test_folders.push_back(
4309ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch      new TestFolder("unique_name", test_date, "uuid1", 0, 0));
43190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  expected_names.push_back("unique_name " + test_date_string);
43290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
43358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  SetupFolders(&test_folders, std::vector<AlbumInfo>(), AlbumImagesMap());
43490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4359ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  FileSystemOperation::FileEntryList contents;
4369ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  FileSystemURL url = CreateURL(kPicasaDirFolders);
4379ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  bool completed = false;
4389ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  ReadDirectoryTestHelper(operation_runner(), url, &contents, &completed);
439868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
4409ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  ASSERT_TRUE(completed);
4419ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  ASSERT_EQ(expected_names.size(), contents.size());
4429ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  for (size_t i = 0; i < contents.size(); ++i) {
443868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_EQ(expected_names[i],
4449ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch              base::FilePath(contents[i].name).AsUTF8Unsafe());
4459ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch    EXPECT_EQ(test_folders[i]->timestamp(), contents[i].last_modified_time);
4469ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch    EXPECT_TRUE(contents[i].is_directory);
44790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
44890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
44990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
45090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)TEST_F(PicasaFileUtilTest, RootFolders) {
451eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ScopedVector<TestFolder> empty_folders_list;
45258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  SetupFolders(&empty_folders_list, std::vector<AlbumInfo>(), AlbumImagesMap());
453eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
45490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  FileSystemOperation::FileEntryList contents;
45590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  FileSystemURL url = CreateURL("");
45690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  bool completed = false;
4579ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch  ReadDirectoryTestHelper(operation_runner(), url, &contents, &completed);
45890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
45990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ASSERT_TRUE(completed);
46090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ASSERT_EQ(2u, contents.size());
46190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
46290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(contents.front().is_directory);
46390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(contents.back().is_directory);
46490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
46590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(0, contents.front().size);
46690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(0, contents.back().size);
46790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
46890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(FILE_PATH_LITERAL("albums"), contents.front().name);
46990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(FILE_PATH_LITERAL("folders"), contents.back().name);
47090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
47190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
47290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)TEST_F(PicasaFileUtilTest, NonexistentFolder) {
47390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ScopedVector<TestFolder> empty_folders_list;
47458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  SetupFolders(&empty_folders_list, std::vector<AlbumInfo>(), AlbumImagesMap());
47590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
47658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  TestNonexistentDirectory(std::string(kPicasaDirFolders) + "/foo");
47758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  TestNonexistentDirectory(std::string(kPicasaDirFolders) + "/foo/bar");
47858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  TestNonexistentDirectory(std::string(kPicasaDirFolders) + "/foo/bar/baz");
47990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
48090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
48190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)TEST_F(PicasaFileUtilTest, FolderContentsTrivial) {
48290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ScopedVector<TestFolder> test_folders;
48390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::Time test_date = base::Time::FromLocalExploded(test_date_exploded);
48490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
48590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  test_folders.push_back(
48690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      new TestFolder("folder-1-empty", test_date, "uid-empty", 0, 0));
48790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  test_folders.push_back(
48890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      new TestFolder("folder-2-images", test_date, "uid-images", 5, 0));
48990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  test_folders.push_back(
49090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      new TestFolder("folder-3-nonimages", test_date, "uid-nonimages", 0, 5));
49190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  test_folders.push_back(
49290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      new TestFolder("folder-4-both", test_date, "uid-both", 5, 5));
49390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
49458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  SetupFolders(&test_folders, std::vector<AlbumInfo>(), AlbumImagesMap());
49590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  VerifyFolderDirectoryList(test_folders);
49690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
49790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
49890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)TEST_F(PicasaFileUtilTest, FolderWithManyFiles) {
49990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ScopedVector<TestFolder> test_folders;
50090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::Time test_date = base::Time::FromLocalExploded(test_date_exploded);
50190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
50290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  test_folders.push_back(
5035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      new TestFolder("folder-many-files", test_date, "uid-both", 50, 50));
50490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
50558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  SetupFolders(&test_folders, std::vector<AlbumInfo>(), AlbumImagesMap());
50690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  VerifyFolderDirectoryList(test_folders);
50790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
50890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
50990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)TEST_F(PicasaFileUtilTest, ManyFolders) {
51090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ScopedVector<TestFolder> test_folders;
51190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::Time test_date = base::Time::FromLocalExploded(test_date_exploded);
51290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  for (unsigned int i = 0; i < 50; ++i) {
51490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::Time date = test_date - base::TimeDelta::FromDays(i);
51590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
51690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    test_folders.push_back(
51790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        new TestFolder(base::StringPrintf("folder-%05d", i),
51890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                       date,
51990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                       base::StringPrintf("uid%05d", i), i % 5, i % 3));
52090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
52190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
52258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  SetupFolders(&test_folders, std::vector<AlbumInfo>(), AlbumImagesMap());
52390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  VerifyFolderDirectoryList(test_folders);
52490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
52590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
52658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)TEST_F(PicasaFileUtilTest, AlbumExistence) {
52758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ScopedVector<TestFolder> test_folders;
52858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  base::Time test_date = base::Time::FromLocalExploded(test_date_exploded);
52958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
53058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  std::vector<AlbumInfo> albums;
53158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  AlbumInfo info;
53258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  info.name = "albumname";
53358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  info.uid = "albumuid";
53458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  info.timestamp = test_date;
53558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  albums.push_back(info);
53658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
53758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  AlbumImagesMap albums_images;
53858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  albums_images[info.uid] = AlbumImages();
53958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
54058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  SetupFolders(&test_folders, albums, albums_images);
54158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
54258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  TestEmptyDirectory(std::string(kPicasaDirAlbums) + "/albumname 2013-04-16");
54358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  TestNonexistentDirectory(std::string(kPicasaDirAlbums) +
54458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                           "/albumname 2013-04-16/toodeep");
54558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  TestNonexistentDirectory(std::string(kPicasaDirAlbums) + "/wrongname");
54658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
54758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
54858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)TEST_F(PicasaFileUtilTest, AlbumContents) {
54958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ScopedVector<TestFolder> test_folders;
55058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  base::Time test_date = base::Time::FromLocalExploded(test_date_exploded);
55158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
55258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  std::vector<AlbumInfo> albums;
55358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  AlbumInfo info;
55458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  info.name = "albumname";
55558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  info.uid = "albumuid";
55658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  info.timestamp = test_date;
55758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  albums.push_back(info);
55858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
55958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  base::ScopedTempDir temp_dir;
56058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
56158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
56258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  base::FilePath image_path = temp_dir.path().AppendASCII("img.jpg");
56358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ASSERT_TRUE(WriteJPEGHeader(image_path));
56458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
56558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  AlbumImagesMap albums_images;
56658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  albums_images[info.uid] = AlbumImages();
56758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  albums_images[info.uid]["mapped_name.jpg"] = image_path;
56858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
56958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  SetupFolders(&test_folders, albums, albums_images);
57058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
57158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  FileSystemOperation::FileEntryList contents;
57258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  FileSystemURL url =
57358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CreateURL(std::string(kPicasaDirAlbums) + "/albumname 2013-04-16");
57458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool completed = false;
57558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ReadDirectoryTestHelper(operation_runner(), url, &contents, &completed);
57658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
57758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ASSERT_TRUE(completed);
57858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ(1u, contents.size());
57958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ("mapped_name.jpg",
58058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            base::FilePath(contents.begin()->name).AsUTF8Unsafe());
58158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_FALSE(contents.begin()->is_directory);
58258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
58358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Create a snapshot file to verify the file path.
58458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  base::RunLoop loop;
5855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error error;
58658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  base::FilePath platform_path_result;
58703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  storage::FileSystemOperationRunner::SnapshotFileCallback snapshot_callback =
58858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      base::Bind(&CreateSnapshotFileTestHelperCallback,
58958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                 &loop,
59058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                 &error,
59158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                 &platform_path_result);
59258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  operation_runner()->CreateSnapshotFile(
59358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CreateURL(std::string(kPicasaDirAlbums) +
59458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                "/albumname 2013-04-16/mapped_name.jpg"),
59558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      snapshot_callback);
59658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  loop.Run();
5975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK, error);
59858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ(image_path, platform_path_result);
59958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
60058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
601868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}  // namespace picasa
602