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