1 // Copyright 2014 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.
5 #include "chrome/browser/media_galleries/media_folder_finder.h"
10 #include "base/bind.h"
11 #include "base/file_util.h"
12 #include "base/files/scoped_temp_dir.h"
13 #include "base/run_loop.h"
14 #include "base/strings/stringprintf.h"
15 #include "base/threading/sequenced_worker_pool.h"
16 #include "chrome/browser/media_galleries/media_scan_types.h"
17 #include "content/public/browser/browser_thread.h"
18 #include "content/public/test/test_browser_thread_bundle.h"
21 class MediaFolderFinderTest : public testing::Test {
23 MediaFolderFinderTest() {
26 virtual ~MediaFolderFinderTest() {
29 virtual void SetUp() OVERRIDE {
30 ASSERT_TRUE(fake_dir_.CreateUniqueTempDir());
33 virtual void TearDown() OVERRIDE {
34 ASSERT_EQ(NULL, media_folder_finder_.get());
38 void CreateMediaFolderFinder(
39 const std::vector<base::FilePath> roots,
40 bool expected_success,
41 const MediaFolderFinder::MediaFolderFinderResults& expected_results) {
42 EXPECT_EQ(NULL, media_folder_finder_.get());
43 received_results_ = false;
44 expected_success_ = expected_success;
45 expected_results_ = expected_results;
46 media_folder_finder_.reset(
47 new MediaFolderFinder(base::Bind(&MediaFolderFinderTest::OnGotResults,
48 base::Unretained(this))));
49 media_folder_finder_->SetRootsForTesting(roots);
53 media_folder_finder_->StartScan();
56 void DeleteMediaFolderFinder() {
57 EXPECT_TRUE(media_folder_finder_.get() != NULL);
58 media_folder_finder_.reset();
61 bool received_results() const {
62 return received_results_;
65 const base::FilePath& fake_dir() {
66 return fake_dir_.path();
69 void CreateTestDir(const base::FilePath& parent_dir) {
70 ASSERT_TRUE(fake_dir().IsParent(parent_dir));
71 ASSERT_TRUE(base::CreateDirectory(parent_dir));
74 void CreateTestFile(const base::FilePath& parent_dir,
75 MediaGalleryScanFileType type,
78 MediaFolderFinder::MediaFolderFinderResults* results) {
79 CreateTestDir(parent_dir);
81 std::string extension;
83 MediaGalleryScanResult& result = (*results)[parent_dir];
85 case MEDIA_GALLERY_SCAN_FILE_TYPE_IMAGE:
88 result.image_count += count;
90 case MEDIA_GALLERY_SCAN_FILE_TYPE_AUDIO:
93 result.audio_count += count;
95 case MEDIA_GALLERY_SCAN_FILE_TYPE_VIDEO:
98 result.video_count += count;
100 case MEDIA_GALLERY_SCAN_FILE_TYPE_UNKNOWN:
103 if (IsEmptyScanResult(result))
104 results->erase(parent_dir);
113 for (size_t i = 0; i < count; ++i) {
114 base::FilePath test_file(parent_dir.AppendASCII("dummy." + extension));
116 file_util::GetUniquePathNumber(test_file,
117 base::FilePath::StringType());
118 if (uniquifier > 0) {
119 test_file = test_file.InsertBeforeExtensionASCII(
120 base::StringPrintf(" (%d)", uniquifier));
121 filesize += uniquifier;
124 std::string dummy_data;
125 dummy_data.resize(filesize);
128 file_util::WriteFile(test_file, dummy_data.c_str(), filesize);
129 ASSERT_GE(bytes_written, 0);
130 ASSERT_EQ(filesize, static_cast<size_t>(bytes_written));
135 base::RunLoop().RunUntilIdle();
136 content::BrowserThread::GetBlockingPool()->FlushForTesting();
139 void RunLoopUntilReceivedCallback() {
140 while (!received_results())
147 const MediaFolderFinder::MediaFolderFinderResults& results) {
148 received_results_ = true;
149 EXPECT_EQ(expected_success_, success);
150 std::set<base::FilePath> expected_keys =
151 GetKeysFromResults(expected_results_);
152 ASSERT_EQ(expected_keys, GetKeysFromResults(results));
153 for (MediaFolderFinder::MediaFolderFinderResults::const_iterator it =
155 it != results.end(); ++it) {
156 const base::FilePath& folder = it->first;
157 const MediaGalleryScanResult& expected = it->second;
158 const MediaGalleryScanResult& actual = results.find(folder)->second;
159 EXPECT_EQ(expected.image_count, actual.image_count)
160 << " Image count for " << folder.value();
161 EXPECT_EQ(expected.audio_count, actual.audio_count)
162 << " Audio count for " << folder.value();
163 EXPECT_EQ(expected.video_count, actual.video_count)
164 << " Video count for " << folder.value();
168 std::set<base::FilePath> GetKeysFromResults(
169 const MediaFolderFinder::MediaFolderFinderResults& results) {
170 std::set<base::FilePath> keys;
171 for (MediaFolderFinder::MediaFolderFinderResults::const_iterator it =
173 it != results.end(); ++it) {
174 keys.insert(it->first);
179 content::TestBrowserThreadBundle thread_bundle_;
181 base::ScopedTempDir fake_dir_;
183 scoped_ptr<MediaFolderFinder> media_folder_finder_;
185 bool expected_success_;
186 MediaFolderFinder::MediaFolderFinderResults expected_results_;
187 bool received_results_;
189 DISALLOW_COPY_AND_ASSIGN(MediaFolderFinderTest);
192 TEST_F(MediaFolderFinderTest, NoScan) {
193 MediaFolderFinder::MediaFolderFinderResults expected_results;
194 std::vector<base::FilePath> folders;
195 folders.push_back(fake_dir());
196 CreateMediaFolderFinder(folders, false, expected_results);
197 DeleteMediaFolderFinder();
198 EXPECT_TRUE(received_results());
201 TEST_F(MediaFolderFinderTest, ScanAndCancel) {
202 MediaFolderFinder::MediaFolderFinderResults expected_results;
203 std::vector<base::FilePath> folders;
204 folders.push_back(fake_dir());
205 CreateMediaFolderFinder(folders, false, expected_results);
207 DeleteMediaFolderFinder();
209 EXPECT_TRUE(received_results());
212 TEST_F(MediaFolderFinderTest, ScanNothing) {
213 MediaFolderFinder::MediaFolderFinderResults expected_results;
214 std::vector<base::FilePath> folders;
215 CreateMediaFolderFinder(folders, true, expected_results);
217 RunLoopUntilReceivedCallback();
218 DeleteMediaFolderFinder();
221 TEST_F(MediaFolderFinderTest, EmptyScan) {
222 MediaFolderFinder::MediaFolderFinderResults expected_results;
223 std::vector<base::FilePath> folders;
224 folders.push_back(fake_dir());
225 CreateMediaFolderFinder(folders, true, expected_results);
227 RunLoopUntilReceivedCallback();
228 DeleteMediaFolderFinder();
231 TEST_F(MediaFolderFinderTest, ScanMediaFiles) {
232 MediaFolderFinder::MediaFolderFinderResults expected_results;
233 std::vector<base::FilePath> folders;
234 folders.push_back(fake_dir());
236 base::FilePath dir1 = fake_dir().AppendASCII("dir1");
237 base::FilePath dir2 = fake_dir().AppendASCII("dir2");
238 base::FilePath dir2_3 = dir2.AppendASCII("dir2_3");
239 base::FilePath dir2_4 = dir2.AppendASCII("dir2_4");
240 base::FilePath dir2_4_5 = dir2_4.AppendASCII("dir2_4_5");
241 base::FilePath dir2_4_empty = dir2_4.AppendASCII("dir2_4_empty");
242 base::FilePath dir_empty = fake_dir().AppendASCII("dir_empty");
244 CreateTestFile(dir1, MEDIA_GALLERY_SCAN_FILE_TYPE_IMAGE, 2, true,
246 CreateTestFile(dir1, MEDIA_GALLERY_SCAN_FILE_TYPE_IMAGE, 1, false,
248 CreateTestFile(dir1, MEDIA_GALLERY_SCAN_FILE_TYPE_UNKNOWN, 1, false,
250 CreateTestFile(dir2_3, MEDIA_GALLERY_SCAN_FILE_TYPE_AUDIO, 4, true,
252 CreateTestFile(dir2_3, MEDIA_GALLERY_SCAN_FILE_TYPE_AUDIO, 3, false,
254 CreateTestFile(dir2_4, MEDIA_GALLERY_SCAN_FILE_TYPE_UNKNOWN, 5, false,
256 CreateTestFile(dir2_4_5, MEDIA_GALLERY_SCAN_FILE_TYPE_IMAGE, 2, true,
258 CreateTestFile(dir2_4_5, MEDIA_GALLERY_SCAN_FILE_TYPE_AUDIO, 4, true,
260 CreateTestFile(dir2_4_5, MEDIA_GALLERY_SCAN_FILE_TYPE_VIDEO, 1, true,
262 CreateTestFile(dir2_4_5, MEDIA_GALLERY_SCAN_FILE_TYPE_IMAGE, 5, false,
264 CreateTestFile(dir2_4_5, MEDIA_GALLERY_SCAN_FILE_TYPE_VIDEO, 3, false,
266 CreateTestFile(dir2_4_5, MEDIA_GALLERY_SCAN_FILE_TYPE_UNKNOWN, 3, true,
268 CreateTestDir(dir2_4_empty);
269 CreateTestDir(dir_empty);
271 CreateMediaFolderFinder(folders, true, expected_results);
273 RunLoopUntilReceivedCallback();
274 DeleteMediaFolderFinder();
277 TEST_F(MediaFolderFinderTest, SkipHiddenFiles) {
278 MediaFolderFinder::MediaFolderFinderResults expected_results;
279 std::vector<base::FilePath> folders;
280 folders.push_back(fake_dir());
282 base::FilePath hidden_dir = fake_dir().AppendASCII(".hidden");
284 CreateTestFile(hidden_dir, MEDIA_GALLERY_SCAN_FILE_TYPE_IMAGE, 2, true,
286 expected_results.erase(hidden_dir);
288 CreateMediaFolderFinder(folders, true, expected_results);
290 RunLoopUntilReceivedCallback();
291 DeleteMediaFolderFinder();
294 TEST_F(MediaFolderFinderTest, ScanIgnoresSmallMediaFiles) {
295 MediaFolderFinder::MediaFolderFinderResults expected_results;
296 std::vector<base::FilePath> folders;
297 folders.push_back(fake_dir());
299 base::FilePath dir1 = fake_dir().AppendASCII("dir1");
300 base::FilePath dir2 = fake_dir().AppendASCII("dir2");
301 base::FilePath dir_empty = fake_dir().AppendASCII("dir_empty");
303 CreateTestFile(dir1, MEDIA_GALLERY_SCAN_FILE_TYPE_IMAGE, 2, true,
305 CreateTestFile(dir1, MEDIA_GALLERY_SCAN_FILE_TYPE_VIDEO, 1, false,
307 CreateTestFile(dir1, MEDIA_GALLERY_SCAN_FILE_TYPE_UNKNOWN, 1, false,
309 CreateTestFile(dir2, MEDIA_GALLERY_SCAN_FILE_TYPE_IMAGE, 1, false,
311 CreateTestFile(dir2, MEDIA_GALLERY_SCAN_FILE_TYPE_AUDIO, 3, false,
313 CreateTestFile(dir2, MEDIA_GALLERY_SCAN_FILE_TYPE_VIDEO, 5, false,
315 CreateTestFile(dir2, MEDIA_GALLERY_SCAN_FILE_TYPE_UNKNOWN, 1, true,
317 CreateTestDir(dir_empty);
318 ASSERT_EQ(1U, expected_results.erase(dir2));
320 CreateMediaFolderFinder(folders, true, expected_results);
322 RunLoopUntilReceivedCallback();
323 DeleteMediaFolderFinder();
326 TEST_F(MediaFolderFinderTest, Overlap) {
327 MediaFolderFinder::MediaFolderFinderResults expected_results;
328 std::vector<base::FilePath> folders;
329 folders.push_back(fake_dir());
330 folders.push_back(fake_dir());
332 base::FilePath dir1 = fake_dir().AppendASCII("dir1");
333 folders.push_back(dir1);
334 folders.push_back(dir1);
336 CreateTestFile(dir1, MEDIA_GALLERY_SCAN_FILE_TYPE_IMAGE, 1, true,
339 CreateMediaFolderFinder(folders, true, expected_results);
341 RunLoopUntilReceivedCallback();
342 DeleteMediaFolderFinder();