itunes_file_util_unittest.cc revision 23730a6e56a168d1879203e4b3819bb36e3d8f1f
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.h" 10#include "base/bind_helpers.h" 11#include "base/file_util.h" 12#include "base/files/scoped_temp_dir.h" 13#include "base/run_loop.h" 14#include "base/synchronization/waitable_event.h" 15#include "base/time/time.h" 16#include "chrome/browser/media_galleries/fileapi/itunes_data_provider.h" 17#include "chrome/browser/media_galleries/fileapi/itunes_file_util.h" 18#include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h" 19#include "chrome/browser/media_galleries/fileapi/media_path_filter.h" 20#include "content/public/browser/browser_thread.h" 21#include "content/public/test/test_browser_thread.h" 22#include "content/public/test/test_file_system_options.h" 23#include "testing/gtest/include/gtest/gtest.h" 24#include "webkit/browser/fileapi/async_file_util.h" 25#include "webkit/browser/fileapi/external_mount_points.h" 26#include "webkit/browser/fileapi/file_system_context.h" 27#include "webkit/browser/fileapi/file_system_operation_context.h" 28#include "webkit/browser/fileapi/file_system_operation_runner.h" 29#include "webkit/browser/quota/mock_special_storage_policy.h" 30 31using fileapi::FileSystemOperationContext; 32using fileapi::FileSystemOperation; 33using fileapi::FileSystemURL; 34 35namespace itunes { 36 37namespace { 38 39void ReadDirectoryTestHelperCallback( 40 base::RunLoop* run_loop, 41 FileSystemOperation::FileEntryList* contents, 42 bool* completed, base::File::Error error, 43 const FileSystemOperation::FileEntryList& file_list, 44 bool has_more) { 45 DCHECK(!*completed); 46 *completed = (!has_more && error == base::File::FILE_OK); 47 *contents = file_list; 48 run_loop->Quit(); 49} 50 51void ReadDirectoryTestHelper(fileapi::FileSystemOperationRunner* runner, 52 const FileSystemURL& url, 53 FileSystemOperation::FileEntryList* contents, 54 bool* completed) { 55 DCHECK(contents); 56 DCHECK(completed); 57 base::RunLoop run_loop; 58 runner->ReadDirectory( 59 url, base::Bind(&ReadDirectoryTestHelperCallback, &run_loop, contents, 60 completed)); 61 run_loop.Run(); 62} 63 64} // namespace 65 66class TestITunesDataProvider : public ITunesDataProvider { 67 public: 68 explicit TestITunesDataProvider(const base::FilePath& fake_library_path) 69 : ITunesDataProvider(fake_library_path) { 70 EXPECT_TRUE(fake_auto_add_dir_.CreateUniqueTempDir()); 71 } 72 73 virtual ~TestITunesDataProvider() {} 74 75 virtual void RefreshData(const ReadyCallback& ready_callback) OVERRIDE { 76 ready_callback.Run(true /* success */); 77 } 78 79 virtual const base::FilePath& auto_add_path() const OVERRIDE { 80 return fake_auto_add_dir_.path(); 81 } 82 83 void SetProvideAutoAddDir(bool provide_auto_add_dir) { 84 if (provide_auto_add_dir) { 85 if (!fake_auto_add_dir_.IsValid()) 86 ASSERT_TRUE(fake_auto_add_dir_.CreateUniqueTempDir()); 87 } else { 88 ASSERT_TRUE(fake_auto_add_dir_.Delete()); 89 } 90 } 91 92 private: 93 base::ScopedTempDir fake_auto_add_dir_; 94}; 95 96class TestITunesFileUtil : public ITunesFileUtil { 97 public: 98 explicit TestITunesFileUtil(MediaPathFilter* media_path_filter, 99 ITunesDataProvider* data_provider) 100 : ITunesFileUtil(media_path_filter), 101 data_provider_(data_provider) { 102 } 103 virtual ~TestITunesFileUtil() {} 104 105 private: 106 virtual ITunesDataProvider* GetDataProvider() OVERRIDE { 107 return data_provider_; 108 } 109 110 ITunesDataProvider* data_provider_; 111}; 112 113class TestMediaFileSystemBackend : public MediaFileSystemBackend { 114 public: 115 TestMediaFileSystemBackend(const base::FilePath& profile_path, 116 ITunesFileUtil* itunes_file_util) 117 : MediaFileSystemBackend( 118 profile_path, 119 MediaFileSystemBackend::MediaTaskRunner().get()), 120 test_file_util_(itunes_file_util) {} 121 122 virtual fileapi::AsyncFileUtil* 123 GetAsyncFileUtil(fileapi::FileSystemType type) OVERRIDE { 124 if (type != fileapi::kFileSystemTypeItunes) 125 return NULL; 126 127 return test_file_util_.get(); 128 } 129 130 private: 131 scoped_ptr<fileapi::AsyncFileUtil> test_file_util_; 132}; 133 134class ItunesFileUtilTest : public testing::Test { 135 public: 136 ItunesFileUtilTest() 137 : io_thread_(content::BrowserThread::IO, &message_loop_) { 138 } 139 virtual ~ItunesFileUtilTest() {} 140 141 void SetUpDataProvider() { 142 ASSERT_TRUE(fake_library_dir_.CreateUniqueTempDir()); 143 ASSERT_EQ( 144 0, 145 base::WriteFile( 146 fake_library_dir_.path().AppendASCII(kITunesLibraryXML), 147 NULL, 148 0)); 149 150 itunes_data_provider_.reset( 151 new TestITunesDataProvider(fake_library_dir_.path())); 152 } 153 154 virtual void SetUp() OVERRIDE { 155 ASSERT_TRUE(profile_dir_.CreateUniqueTempDir()); 156 157 scoped_refptr<quota::SpecialStoragePolicy> storage_policy = 158 new quota::MockSpecialStoragePolicy(); 159 160 // Initialize fake ItunesDataProvider on media task runner thread. 161 MediaFileSystemBackend::MediaTaskRunner()->PostTask( 162 FROM_HERE, 163 base::Bind(&ItunesFileUtilTest::SetUpDataProvider, 164 base::Unretained(this))); 165 base::WaitableEvent event(true, false /* initially_signalled */); 166 MediaFileSystemBackend::MediaTaskRunner()->PostTask( 167 FROM_HERE, 168 base::Bind(&base::WaitableEvent::Signal, base::Unretained(&event))); 169 event.Wait(); 170 171 media_path_filter_.reset(new MediaPathFilter()); 172 ScopedVector<fileapi::FileSystemBackend> additional_providers; 173 additional_providers.push_back(new TestMediaFileSystemBackend( 174 profile_dir_.path(), 175 new TestITunesFileUtil(media_path_filter_.get(), 176 itunes_data_provider_.get()))); 177 178 file_system_context_ = new fileapi::FileSystemContext( 179 base::MessageLoopProxy::current().get(), 180 base::MessageLoopProxy::current().get(), 181 fileapi::ExternalMountPoints::CreateRefCounted().get(), 182 storage_policy.get(), 183 NULL, 184 additional_providers.Pass(), 185 std::vector<fileapi::URLRequestAutoMountHandler>(), 186 profile_dir_.path(), 187 content::CreateAllowFileAccessOptions()); 188 } 189 190 protected: 191 void TestNonexistentFolder(const std::string& path_append) { 192 FileSystemOperation::FileEntryList contents; 193 FileSystemURL url = CreateURL(path_append); 194 bool completed = false; 195 ReadDirectoryTestHelper(operation_runner(), url, &contents, &completed); 196 197 ASSERT_FALSE(completed); 198 } 199 200 FileSystemURL CreateURL(const std::string& virtual_path) const { 201 return file_system_context_->CreateCrackedFileSystemURL( 202 GURL("http://www.example.com"), fileapi::kFileSystemTypeItunes, 203 base::FilePath::FromUTF8Unsafe(virtual_path)); 204 } 205 206 fileapi::FileSystemOperationRunner* operation_runner() const { 207 return file_system_context_->operation_runner(); 208 } 209 210 scoped_refptr<fileapi::FileSystemContext> file_system_context() const { 211 return file_system_context_; 212 } 213 214 TestITunesDataProvider* data_provider() const { 215 return itunes_data_provider_.get(); 216 } 217 218 private: 219 base::MessageLoop message_loop_; 220 content::TestBrowserThread io_thread_; 221 222 base::ScopedTempDir profile_dir_; 223 base::ScopedTempDir fake_library_dir_; 224 225 scoped_refptr<fileapi::FileSystemContext> file_system_context_; 226 scoped_ptr<MediaPathFilter> media_path_filter_; 227 scoped_ptr<TestITunesDataProvider> itunes_data_provider_; 228 229 DISALLOW_COPY_AND_ASSIGN(ItunesFileUtilTest); 230}; 231 232TEST_F(ItunesFileUtilTest, RootContents) { 233 FileSystemOperation::FileEntryList contents; 234 FileSystemURL url = CreateURL(""); 235 bool completed = false; 236 ReadDirectoryTestHelper(operation_runner(), url, &contents, &completed); 237 238 ASSERT_TRUE(completed); 239 ASSERT_EQ(2u, contents.size()); 240 241 EXPECT_FALSE(contents.front().is_directory); 242 EXPECT_TRUE(contents.back().is_directory); 243 244 EXPECT_EQ(base::FilePath::FromUTF8Unsafe(kITunesLibraryXML).value(), 245 contents.front().name); 246 EXPECT_EQ(base::FilePath::FromUTF8Unsafe(kITunesMediaDir).value(), 247 contents.back().name); 248} 249 250TEST_F(ItunesFileUtilTest, ItunesMediaDirectoryContentsNoAutoAdd) { 251 data_provider()->SetProvideAutoAddDir(false); 252 253 FileSystemOperation::FileEntryList contents; 254 FileSystemURL url = CreateURL(kITunesMediaDir); 255 bool completed = false; 256 ReadDirectoryTestHelper(operation_runner(), url, &contents, &completed); 257 258 ASSERT_TRUE(completed); 259 ASSERT_EQ(1u, contents.size()); 260 261 EXPECT_TRUE(contents.front().is_directory); 262 EXPECT_EQ(base::FilePath::FromUTF8Unsafe(kITunesMusicDir).value(), 263 contents.back().name); 264} 265 266TEST_F(ItunesFileUtilTest, ItunesMediaDirectoryContentsAutoAdd) { 267 data_provider()->SetProvideAutoAddDir(true); 268 269 FileSystemOperation::FileEntryList contents; 270 FileSystemURL url = CreateURL(kITunesMediaDir); 271 bool completed = false; 272 ReadDirectoryTestHelper(operation_runner(), url, &contents, &completed); 273 274 ASSERT_TRUE(completed); 275 ASSERT_EQ(2u, contents.size()); 276 277 EXPECT_TRUE(contents.front().is_directory); 278 EXPECT_TRUE(contents.back().is_directory); 279 280 EXPECT_EQ(base::FilePath::FromUTF8Unsafe(kITunesAutoAddDir).value(), 281 contents.front().name); 282 EXPECT_EQ(base::FilePath::FromUTF8Unsafe(kITunesMusicDir).value(), 283 contents.back().name); 284} 285 286TEST_F(ItunesFileUtilTest, ItunesAutoAddDirEnumerate) { 287 data_provider()->SetProvideAutoAddDir(true); 288 ASSERT_EQ(0, base::WriteFile( 289 data_provider()->auto_add_path().AppendASCII("baz.ogg"), NULL, 0)); 290 291 FileSystemOperation::FileEntryList contents; 292 FileSystemURL url = CreateURL( 293 std::string(kITunesMediaDir) + "/" + kITunesAutoAddDir); 294 bool completed = false; 295 296 ReadDirectoryTestHelper(operation_runner(), url, &contents, &completed); 297 ASSERT_TRUE(completed); 298 ASSERT_EQ(1u, contents.size()); 299 EXPECT_FALSE(contents.front().is_directory); 300 EXPECT_EQ(base::FilePath().AppendASCII("baz.ogg").value(), 301 contents.front().name); 302} 303 304TEST_F(ItunesFileUtilTest, ItunesAutoAddDirEnumerateNested) { 305 data_provider()->SetProvideAutoAddDir(true); 306 base::FilePath nested_dir = 307 data_provider()->auto_add_path().AppendASCII("foo").AppendASCII("bar"); 308 ASSERT_TRUE(base::CreateDirectory(nested_dir)); 309 ASSERT_EQ(0, 310 base::WriteFile(nested_dir.AppendASCII("baz.ogg"), NULL, 0)); 311 312 FileSystemOperation::FileEntryList contents; 313 FileSystemURL url = CreateURL( 314 std::string(kITunesMediaDir) + "/" + kITunesAutoAddDir); 315 bool completed = false; 316 317 ReadDirectoryTestHelper(operation_runner(), url, &contents, &completed); 318 ASSERT_TRUE(completed); 319 ASSERT_EQ(1u, contents.size()); 320 EXPECT_TRUE(contents.front().is_directory); 321 EXPECT_EQ(base::FilePath().AppendASCII("foo").value(), contents.front().name); 322 323 contents.clear(); 324 url = CreateURL( 325 std::string(kITunesMediaDir) + "/" + kITunesAutoAddDir + "/foo"); 326 completed = false; 327 ReadDirectoryTestHelper(operation_runner(), url, &contents, &completed); 328 ASSERT_TRUE(completed); 329 ASSERT_EQ(1u, contents.size()); 330 EXPECT_TRUE(contents.front().is_directory); 331 EXPECT_EQ(base::FilePath().AppendASCII("bar").value(), contents.front().name); 332 333 contents.clear(); 334 url = CreateURL( 335 std::string(kITunesMediaDir) + "/" + kITunesAutoAddDir + "/foo/bar"); 336 completed = false; 337 ReadDirectoryTestHelper(operation_runner(), url, &contents, &completed); 338 ASSERT_TRUE(completed); 339 ASSERT_EQ(1u, contents.size()); 340 EXPECT_FALSE(contents.front().is_directory); 341 EXPECT_EQ(base::FilePath().AppendASCII("baz.ogg").value(), 342 contents.front().name); 343} 344 345} // namespace itunes 346