Give names to all utility processes.
[chromium-blink-merge.git] / chrome / browser / media_galleries / fileapi / iphoto_data_provider_browsertest.cc
bloba9886d2c4cb291b9ae31ac080a4c3c9ce7a25e41
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.
5 #include <string>
6 #include <vector>
8 #include "base/bind.h"
9 #include "base/files/file_path.h"
10 #include "base/files/file_util.h"
11 #include "base/files/scoped_temp_dir.h"
12 #include "base/format_macros.h"
13 #include "base/logging.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/message_loop/message_loop.h"
16 #include "base/run_loop.h"
17 #include "base/stl_util.h"
18 #include "base/strings/stringprintf.h"
19 #include "chrome/browser/media_galleries/fileapi/iphoto_data_provider.h"
20 #include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h"
21 #include "chrome/browser/media_galleries/imported_media_gallery_registry.h"
22 #include "chrome/test/base/in_process_browser_test.h"
23 #include "content/public/browser/browser_thread.h"
24 #include "url/gurl.h"
26 using base::FilePath;
28 namespace iphoto {
30 class TestIPhotoDataProvider : public IPhotoDataProvider {
31 public:
32 TestIPhotoDataProvider(const base::FilePath& xml_library_path,
33 const base::Closure& callback)
34 : IPhotoDataProvider(xml_library_path),
35 callback_(callback) {
37 ~TestIPhotoDataProvider() override {}
39 private:
40 void OnLibraryChanged(const base::FilePath& path, bool error) override {
41 IPhotoDataProvider::OnLibraryChanged(path, error);
42 callback_.Run();
45 base::Closure callback_;
47 DISALLOW_COPY_AND_ASSIGN(TestIPhotoDataProvider);
50 class IPhotoDataProviderTest : public InProcessBrowserTest {
51 public:
52 IPhotoDataProviderTest() {}
54 protected:
55 void SetUp() override {
56 ASSERT_TRUE(library_dir_.CreateUniqueTempDir());
57 WriteLibraryInternal();
58 // The ImportedMediaGalleryRegistry is created on which ever thread calls
59 // GetInstance() first. It shouldn't matter what thread creates, however
60 // in practice it is always created on the UI thread, so this calls
61 // GetInstance here to mirror those real conditions.
62 ImportedMediaGalleryRegistry::GetInstance();
63 InProcessBrowserTest::SetUp();
66 void RunTest() {
67 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
68 base::RunLoop loop;
69 quit_closure_ = loop.QuitClosure();
70 MediaFileSystemBackend::MediaTaskRunner()->PostTask(
71 FROM_HERE,
72 base::Bind(&IPhotoDataProviderTest::StartTestOnMediaTaskRunner,
73 base::Unretained(this)));
74 loop.Run();
77 void WriteLibrary(const base::Closure& callback) {
78 SetLibraryChangeCallback(callback);
79 WriteLibraryInternal();
82 void SetLibraryChangeCallback(const base::Closure& callback) {
83 EXPECT_TRUE(library_changed_callback_.is_null());
84 library_changed_callback_ = callback;
87 IPhotoDataProvider* data_provider() const {
88 return ImportedMediaGalleryRegistry::IPhotoDataProvider();
91 const base::FilePath& library_dir() const {
92 return library_dir_.path();
95 base::FilePath XmlFile() const {
96 return library_dir_.path().AppendASCII("library.xml");
99 // Start the test. The data provider is refreshed before calling StartTest
100 // and the result of the refresh is passed in.
101 virtual void StartTest(bool parse_success) = 0;
103 void TestDone() {
104 DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
105 ImportedMediaGalleryRegistry* imported_registry =
106 ImportedMediaGalleryRegistry::GetInstance();
107 imported_registry->iphoto_data_provider_.reset();
108 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
109 quit_closure_);
112 // Override to provide a full library string.
113 virtual std::string GetLibraryString() {
114 return "<plist><dict>\n</dict></plist>\n";
117 private:
118 void StartTestOnMediaTaskRunner() {
119 DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
120 ImportedMediaGalleryRegistry* imported_registry =
121 ImportedMediaGalleryRegistry::GetInstance();
122 imported_registry->iphoto_data_provider_.reset(
123 new TestIPhotoDataProvider(
124 XmlFile(),
125 base::Bind(&IPhotoDataProviderTest::OnLibraryChanged,
126 base::Unretained(this))));
127 data_provider()->RefreshData(base::Bind(&IPhotoDataProviderTest::StartTest,
128 base::Unretained(this)));
131 void OnLibraryChanged() {
132 DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
133 if (!library_changed_callback_.is_null()) {
134 library_changed_callback_.Run();
135 library_changed_callback_.Reset();
139 void WriteLibraryInternal() {
140 std::string xml = GetLibraryString();
141 ASSERT_EQ(static_cast<int>(xml.size()),
142 base::WriteFile(XmlFile(), xml.c_str(), xml.size()));
145 base::ScopedTempDir library_dir_;
147 base::Closure library_changed_callback_;
149 base::Closure quit_closure_;
151 DISALLOW_COPY_AND_ASSIGN(IPhotoDataProviderTest);
154 class IPhotoDataProviderBasicTest : public IPhotoDataProviderTest {
155 public:
156 IPhotoDataProviderBasicTest() {}
158 std::string GetLibraryString() override {
159 return "<plist><dict>\n"
160 "<key>List of Albums</key>\n"
161 "<array>"
162 " <dict>\n"
163 " <key>AlbumId</key>"
164 " <integer>14</integer>"
165 " <key>AlbumName</key>"
166 " <string>Album1</string>"
167 " <key>KeyList</key>"
168 " <array>"
169 " <string>1</string>"
170 " <string>3</string>" // [3] and [4] are name dupes
171 " <string>4</string>"
172 " </array>"
173 " </dict>\n"
174 " <dict>\n"
175 " <key>AlbumId</key>"
176 " <integer>15</integer>"
177 " <key>AlbumName</key>"
178 " <string>Album2</string>"
179 " <key>KeyList</key>"
180 " <array>"
181 " <string>2</string>"
182 " </array>"
183 " </dict>\n"
184 " <dict>\n"
185 " <key>AlbumId</key>"
186 " <integer>16</integer>"
187 " <key>AlbumName</key>"
188 " <string>Album5</string>"
189 " <key>KeyList</key>"
190 " <array>"
191 " <string>5</string>" // A name dupe of [2], but in another album.
192 " </array>"
193 " </dict>\n"
194 "</array>\n"
195 "<key>Master Image List</key>\n"
196 "<dict>\n"
197 " <key>1</key>\n"
198 " <dict>\n"
199 " <key>MediaType</key>"
200 " <string>Image</string>"
201 " <key>Caption</key>"
202 " <string>caption</string>"
203 " <key>GUID</key>\n"
204 " <string>guid1</string>"
205 " <key>ImagePath</key>"
206 " <string>/vol/path1.jpg</string>"
207 " <key>ThumbPath</key>"
208 " <string>/vol/thumb1.jpg</string>"
209 " </dict>\n"
210 " <key>2</key>\n"
211 " <dict>\n"
212 " <key>MediaType</key>"
213 " <string>Image</string>"
214 " <key>Caption</key>"
215 " <string>caption2</string>"
216 " <key>GUID</key>\n"
217 " <string>guid2</string>"
218 " <key>ImagePath</key>"
219 " <string>/vol/path2.jpg</string>"
220 " <key>ThumbPath</key>"
221 " <string>/vol/thumb2.jpg</string>"
222 " </dict>\n"
223 " <key>3</key>\n"
224 " <dict>\n"
225 " <key>MediaType</key>"
226 " <string>Image</string>"
227 " <key>Caption</key>"
228 " <string>caption3</string>"
229 " <key>GUID</key>\n"
230 " <string>guid3</string>"
231 " <key>ImagePath</key>"
232 " <string>/vol/path3.jpg</string>"
233 " <key>ThumbPath</key>"
234 " <string>/vol/thumb3.jpg</string>"
235 " </dict>\n"
236 " <key>4</key>\n" // A name duplicate of [3] in another path.
237 " <dict>\n"
238 " <key>MediaType</key>"
239 " <string>Image</string>"
240 " <key>Caption</key>"
241 " <string>caption</string>"
242 " <key>GUID</key>\n"
243 " <string>guid3</string>"
244 " <key>ImagePath</key>"
245 " <string>/vol/dupe/path3.jpg</string>"
246 " <key>ThumbPath</key>"
247 " <string>/vol/dupe/thumb3.jpg</string>"
248 " </dict>\n"
249 " <key>5</key>\n" // A name duplicate of [2] in another path.
250 " <dict>\n"
251 " <key>MediaType</key>"
252 " <string>Image</string>"
253 " <key>Caption</key>"
254 " <string>caption5</string>"
255 " <key>GUID</key>\n"
256 " <string>guid2</string>"
257 " <key>ImagePath</key>"
258 " <string>/vol/dupe/path2.jpg</string>"
259 " <key>ThumbPath</key>"
260 " <string>/vol/dupe/thumb2.jpg</string>"
261 " <key>OriginalPath</key>" \
262 " <string>/original/vol/another2.jpg</string>" \
263 " </dict>\n"
264 "</dict>\n"
265 "</dict></plist>\n";
268 void StartTest(bool parse_success) override {
269 EXPECT_TRUE(parse_success);
271 std::vector<std::string> names = data_provider()->GetAlbumNames();
272 EXPECT_EQ(3U, names.size());
273 EXPECT_EQ("Album1", names[0]);
275 EXPECT_EQ(FilePath("/vol/path1.jpg").value(),
276 data_provider()->GetPhotoLocationInAlbum(
277 "Album1", "path1.jpg").value());
278 EXPECT_EQ(FilePath("/vol/path3.jpg").value(),
279 data_provider()->GetPhotoLocationInAlbum(
280 "Album1", "path3.jpg").value());
281 EXPECT_EQ(FilePath("/vol/dupe/path3.jpg").value(),
282 data_provider()->GetPhotoLocationInAlbum(
283 "Album1", "path3(4).jpg").value());
284 EXPECT_EQ(FilePath().value(),
285 data_provider()->GetPhotoLocationInAlbum(
286 "Album1", "path5.jpg").value());
288 // path2.jpg is name-duped, but in different albums, and so should not
289 // be mangled.
290 EXPECT_EQ(FilePath("/vol/dupe/path2.jpg").value(),
291 data_provider()->GetPhotoLocationInAlbum(
292 "Album5", "path2.jpg").value());
293 EXPECT_EQ(FilePath("/vol/path2.jpg").value(),
294 data_provider()->GetPhotoLocationInAlbum(
295 "Album2", "path2.jpg").value());
297 std::map<std::string, base::FilePath> photos =
298 data_provider()->GetAlbumContents("nonexistent");
299 EXPECT_EQ(0U, photos.size());
300 photos = data_provider()->GetAlbumContents("Album1");
301 EXPECT_EQ(3U, photos.size());
302 EXPECT_TRUE(ContainsKey(photos, "path1.jpg"));
303 EXPECT_FALSE(ContainsKey(photos, "path2.jpg"));
304 EXPECT_TRUE(ContainsKey(photos, "path3.jpg"));
305 EXPECT_TRUE(ContainsKey(photos, "path3(4).jpg"));
306 EXPECT_EQ(FilePath("/vol/path1.jpg").value(), photos["path1.jpg"].value());
307 EXPECT_EQ(FilePath("/vol/path3.jpg").value(),
308 photos["path3.jpg"].value());
309 EXPECT_EQ(FilePath("/vol/dupe/path3.jpg").value(),
310 photos["path3(4).jpg"].value());
312 photos = data_provider()->GetAlbumContents("Album2");
313 EXPECT_EQ(1U, photos.size());
314 EXPECT_TRUE(ContainsKey(photos, "path2.jpg"));
316 EXPECT_FALSE(data_provider()->HasOriginals("Album1"));
317 EXPECT_TRUE(data_provider()->HasOriginals("Album5"));
318 std::map<std::string, base::FilePath> originals =
319 data_provider()->GetOriginals("Album1");
320 EXPECT_EQ(0U, originals.size());
321 originals = data_provider()->GetOriginals("Album5");
322 EXPECT_EQ(1U, originals.size());
323 EXPECT_TRUE(ContainsKey(originals, "path2.jpg"));
324 EXPECT_FALSE(ContainsKey(originals, "path1.jpg"));
325 EXPECT_EQ(FilePath("/original/vol/another2.jpg").value(),
326 originals["path2.jpg"].value());
327 base::FilePath original_path =
328 data_provider()->GetOriginalPhotoLocation("Album5", "path2.jpg");
329 EXPECT_EQ(FilePath("/original/vol/another2.jpg").value(),
330 original_path.value());
332 TestDone();
335 private:
336 DISALLOW_COPY_AND_ASSIGN(IPhotoDataProviderBasicTest);
339 class IPhotoDataProviderRefreshTest : public IPhotoDataProviderTest {
340 public:
341 IPhotoDataProviderRefreshTest() {}
343 std::string another_album;
345 std::string GetLibraryString() override {
346 return "<plist><dict>\n"
347 "<key>List of Albums</key>\n"
348 "<array>"
349 " <dict>"
350 " <key>AlbumId</key>"
351 " <integer>14</integer>"
352 " <key>AlbumName</key>"
353 " <string>Album1</string>"
354 " <key>KeyList</key>"
355 " <array>"
356 " <string>1</string>"
357 " </array>"
358 " </dict>\n" +
359 another_album +
360 "</array>\n"
361 "<key>Master Image List</key>\n"
362 "<dict>\n"
363 " <key>1</key>\n"
364 " <dict>\n"
365 " <key>MediaType</key>"
366 " <string>Image</string>"
367 " <key>Caption1</key>"
368 " <string>caption</string>"
369 " <key>GUID</key>\n"
370 " <string>guid1</string>"
371 " <key>ImagePath</key>"
372 " <string>/vol/path1.jpg</string>"
373 " <key>ThumbPath</key>"
374 " <string>/vol/thumb1.jpg</string>"
375 " </dict>\n"
376 "</dict>\n"
377 "</dict></plist>\n";
380 void StartTest(bool parse_success) override {
381 EXPECT_TRUE(parse_success);
383 EXPECT_EQ(FilePath("/vol/path1.jpg"),
384 data_provider()->GetPhotoLocationInAlbum("Album1", "path1.jpg"));
385 std::vector<std::string> names = data_provider()->GetAlbumNames();
386 EXPECT_EQ(1U, names.size());
387 EXPECT_EQ("Album1", names[0]);
389 another_album =
390 " <dict>"
391 " <key>AlbumId</key>"
392 " <integer>14</integer>"
393 " <key>AlbumName</key>"
394 " <string>Another Album</string>"
395 " <key>KeyList</key>"
396 " <array>"
397 " <string>1</string>"
398 " </array>"
399 " </dict>\n";
401 WriteLibrary(base::Bind(&IPhotoDataProviderRefreshTest::CheckAfterWrite,
402 base::Unretained(this)));
405 void CheckAfterWrite() {
406 // No change -- data has not been parsed.
407 EXPECT_EQ(FilePath("/vol/path1.jpg"),
408 data_provider()->GetPhotoLocationInAlbum("Album1", "path1.jpg"));
409 std::vector<std::string> names = data_provider()->GetAlbumNames();
410 EXPECT_EQ(1U, names.size());
411 EXPECT_EQ("Album1", names[0]);
413 data_provider()->RefreshData(
414 base::Bind(&IPhotoDataProviderRefreshTest::CheckRefresh,
415 base::Unretained(this)));
418 void CheckRefresh(bool is_valid) {
419 EXPECT_TRUE(is_valid);
421 EXPECT_EQ(FilePath("/vol/path1.jpg"),
422 data_provider()->GetPhotoLocationInAlbum("Album1", "path1.jpg"));
423 std::vector<std::string> names = data_provider()->GetAlbumNames();
424 EXPECT_EQ(2U, names.size());
425 if (names.size() == 2U) {
426 EXPECT_EQ("Album1", names[0]);
427 EXPECT_EQ("Another Album", names[1]);
430 TestDone();
433 private:
434 DISALLOW_COPY_AND_ASSIGN(IPhotoDataProviderRefreshTest);
437 class IPhotoDataProviderInvalidTest : public IPhotoDataProviderTest {
438 public:
439 IPhotoDataProviderInvalidTest() {}
441 void StartTest(bool parse_success) override {
442 EXPECT_TRUE(parse_success);
444 SetLibraryChangeCallback(
445 base::Bind(&IPhotoDataProvider::RefreshData,
446 base::Unretained(data_provider()),
447 base::Bind(&IPhotoDataProviderInvalidTest::CheckInvalid,
448 base::Unretained(this))));
449 EXPECT_EQ(1L, base::WriteFile(XmlFile(), " ", 1));
452 void CheckInvalid(bool is_valid) {
453 EXPECT_FALSE(is_valid);
454 TestDone();
457 private:
458 DISALLOW_COPY_AND_ASSIGN(IPhotoDataProviderInvalidTest);
461 IN_PROC_BROWSER_TEST_F(IPhotoDataProviderBasicTest, BasicTest) {
462 RunTest();
465 IN_PROC_BROWSER_TEST_F(IPhotoDataProviderRefreshTest, RefreshTest) {
466 RunTest();
469 IN_PROC_BROWSER_TEST_F(IPhotoDataProviderInvalidTest, InvalidTest) {
470 RunTest();
473 } // namespace iphoto