NaCl: Update revision in DEPS, r12770 -> r12773
[chromium-blink-merge.git] / chrome / browser / media_galleries / fileapi / itunes_data_provider_browsertest.cc
blobe14acbf10c28caa47cccffcc349c0103d40f692b
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/file_util.h"
10 #include "base/files/file_path.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/strings/stringprintf.h"
18 #include "chrome/browser/media_galleries/fileapi/itunes_data_provider.h"
19 #include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h"
20 #include "chrome/browser/media_galleries/imported_media_gallery_registry.h"
21 #include "chrome/test/base/in_process_browser_test.h"
22 #include "content/public/browser/browser_thread.h"
23 #include "url/gurl.h"
25 namespace itunes {
27 namespace {
29 struct LibraryEntry {
30 LibraryEntry(const std::string& artist, const std::string& album,
31 const base::FilePath& location)
32 : artist(artist),
33 album(album),
34 location(location) {
36 std::string artist;
37 std::string album;
38 base::FilePath location;
41 } // namespace
43 class TestITunesDataProvider : public ITunesDataProvider {
44 public:
45 TestITunesDataProvider(const base::FilePath& xml_library_path,
46 const base::Closure& callback)
47 : ITunesDataProvider(xml_library_path),
48 callback_(callback) {
50 virtual ~TestITunesDataProvider() {}
52 private:
53 virtual void OnLibraryChanged(const base::FilePath& path,
54 bool error) OVERRIDE {
55 ITunesDataProvider::OnLibraryChanged(path, error);
56 callback_.Run();
59 base::Closure callback_;
61 DISALLOW_COPY_AND_ASSIGN(TestITunesDataProvider);
64 class ITunesDataProviderTest : public InProcessBrowserTest {
65 public:
66 ITunesDataProviderTest() {}
67 virtual ~ITunesDataProviderTest() {}
69 protected:
70 virtual void SetUp() OVERRIDE {
71 ASSERT_TRUE(library_dir_.CreateUniqueTempDir());
72 WriteLibraryInternal(SetUpLibrary());
73 // The ImportedMediaGalleryRegistry is created on which ever thread calls
74 // GetInstance() first. It shouldn't matter what thread creates, however
75 // in practice it is always created on the UI thread, so this calls
76 // GetInstance here to mirror those real conditions.
77 ImportedMediaGalleryRegistry::GetInstance();
78 InProcessBrowserTest::SetUp();
81 void RunTest() {
82 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
83 base::RunLoop loop;
84 quit_closure_ = loop.QuitClosure();
85 MediaFileSystemBackend::MediaTaskRunner()->PostTask(
86 FROM_HERE,
87 base::Bind(&ITunesDataProviderTest::StartTestOnMediaTaskRunner,
88 base::Unretained(this)));
89 loop.Run();
92 void WriteLibrary(const std::vector<LibraryEntry>& entries,
93 const base::Closure& callback) {
94 SetLibraryChangeCallback(callback);
95 WriteLibraryInternal(entries);
98 void SetLibraryChangeCallback(const base::Closure& callback) {
99 EXPECT_TRUE(library_changed_callback_.is_null());
100 library_changed_callback_ = callback;
103 ITunesDataProvider* data_provider() const {
104 return ImportedMediaGalleryRegistry::ITunesDataProvider();
107 const base::FilePath& library_dir() const {
108 return library_dir_.path();
111 base::FilePath XmlFile() const {
112 return library_dir_.path().AppendASCII("library.xml");
115 void ExpectTrackLocation(const std::string& artist, const std::string& album,
116 const std::string& track_name) {
117 base::FilePath track =
118 library_dir().AppendASCII(track_name).NormalizePathSeparators();
119 EXPECT_EQ(track.value(),
120 data_provider()->GetTrackLocation(
121 artist, album, track_name).NormalizePathSeparators().value());
124 void ExpectNoTrack(const std::string& artist, const std::string& album,
125 const std::string& track_name) {
126 EXPECT_TRUE(data_provider()->GetTrackLocation(
127 artist, album, track_name).empty()) << track_name;
131 // Get the initial set of library entries, called by SetUp. If no entries
132 // are returned the xml file is not created.
133 virtual std::vector<LibraryEntry> SetUpLibrary() {
134 return std::vector<LibraryEntry>();
137 // Start the test. The data provider is refreshed before calling StartTest
138 // and the result of the refresh is passed in.
139 virtual void StartTest(bool parse_success) = 0;
141 void TestDone() {
142 DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
143 ImportedMediaGalleryRegistry* imported_registry =
144 ImportedMediaGalleryRegistry::GetInstance();
145 imported_registry->itunes_data_provider_.reset();
146 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
147 quit_closure_);
150 private:
151 void StartTestOnMediaTaskRunner() {
152 DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
153 ImportedMediaGalleryRegistry* imported_registry =
154 ImportedMediaGalleryRegistry::GetInstance();
155 imported_registry->itunes_data_provider_.reset(
156 new TestITunesDataProvider(
157 XmlFile(),
158 base::Bind(&ITunesDataProviderTest::OnLibraryChanged,
159 base::Unretained(this))));
160 data_provider()->RefreshData(base::Bind(&ITunesDataProviderTest::StartTest,
161 base::Unretained(this)));
164 void OnLibraryChanged() {
165 DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
166 if (!library_changed_callback_.is_null()) {
167 library_changed_callback_.Run();
168 library_changed_callback_.Reset();
172 void WriteLibraryInternal(const std::vector<LibraryEntry>& entries) {
173 if (!entries.size())
174 return;
175 std::string xml = "<plist><dict><key>Tracks</key><dict>\n";
176 for (size_t i = 0; i < entries.size(); ++i) {
177 std::string separator;
178 #if defined(OS_WIN)
179 separator = "/";
180 #endif
181 GURL location("file://localhost" + separator +
182 entries[i].location.AsUTF8Unsafe());
183 std::string entry_string = base::StringPrintf(
184 "<key>%" PRIuS "</key><dict>\n"
185 " <key>Track ID</key><integer>%" PRIuS "</integer>\n"
186 " <key>Location</key><string>%s</string>\n"
187 " <key>Artist</key><string>%s</string>\n"
188 " <key>Album</key><string>%s</string>\n"
189 "</dict>\n",
190 i + 1, i + 1, location.spec().c_str(), entries[i].artist.c_str(),
191 entries[i].album.c_str());
192 xml += entry_string;
194 xml += "</dict></dict></plist>\n";
195 ASSERT_EQ(static_cast<int>(xml.size()),
196 file_util::WriteFile(XmlFile(), xml.c_str(), xml.size()));
199 base::ScopedTempDir library_dir_;
201 base::Closure library_changed_callback_;
203 base::Closure quit_closure_;
205 DISALLOW_COPY_AND_ASSIGN(ITunesDataProviderTest);
208 class ITunesDataProviderBasicTest : public ITunesDataProviderTest {
209 public:
210 ITunesDataProviderBasicTest() {}
211 virtual ~ITunesDataProviderBasicTest() {}
213 virtual std::vector<LibraryEntry> SetUpLibrary() OVERRIDE {
214 base::FilePath track = library_dir().AppendASCII("Track.mp3");
215 std::vector<LibraryEntry> entries;
216 entries.push_back(LibraryEntry("Artist", "Album", track));
217 return entries;
220 virtual void StartTest(bool parse_success) OVERRIDE {
221 EXPECT_TRUE(parse_success);
223 // KnownArtist
224 EXPECT_TRUE(data_provider()->KnownArtist("Artist"));
225 EXPECT_FALSE(data_provider()->KnownArtist("Artist2"));
227 // KnownAlbum
228 EXPECT_TRUE(data_provider()->KnownAlbum("Artist", "Album"));
229 EXPECT_FALSE(data_provider()->KnownAlbum("Artist", "Album2"));
230 EXPECT_FALSE(data_provider()->KnownAlbum("Artist2", "Album"));
232 // GetTrackLocation
233 ExpectTrackLocation("Artist", "Album", "Track.mp3");
234 ExpectNoTrack("Artist", "Album", "Track2.mp3");
235 ExpectNoTrack("Artist", "Album2", "Track.mp3");
236 ExpectNoTrack("Artist2", "Album", "Track.mp3");
238 // GetArtistNames
239 std::set<ITunesDataProvider::ArtistName> artists =
240 data_provider()->GetArtistNames();
241 ASSERT_EQ(1U, artists.size());
242 EXPECT_EQ("Artist", *artists.begin());
244 // GetAlbumNames
245 std::set<ITunesDataProvider::AlbumName> albums =
246 data_provider()->GetAlbumNames("Artist");
247 ASSERT_EQ(1U, albums.size());
248 EXPECT_EQ("Album", *albums.begin());
250 albums = data_provider()->GetAlbumNames("Artist2");
251 EXPECT_EQ(0U, albums.size());
253 // GetAlbum
254 base::FilePath track =
255 library_dir().AppendASCII("Track.mp3").NormalizePathSeparators();
256 ITunesDataProvider::Album album =
257 data_provider()->GetAlbum("Artist", "Album");
258 ASSERT_EQ(1U, album.size());
259 EXPECT_EQ(track.BaseName().AsUTF8Unsafe(), album.begin()->first);
260 EXPECT_EQ(track.value(),
261 album.begin()->second.NormalizePathSeparators().value());
263 album = data_provider()->GetAlbum("Artist", "Album2");
264 EXPECT_EQ(0U, album.size());
266 album = data_provider()->GetAlbum("Artist2", "Album");
267 EXPECT_EQ(0U, album.size());
269 TestDone();
272 private:
273 DISALLOW_COPY_AND_ASSIGN(ITunesDataProviderBasicTest);
276 class ITunesDataProviderRefreshTest : public ITunesDataProviderTest {
277 public:
278 ITunesDataProviderRefreshTest() {}
279 virtual ~ITunesDataProviderRefreshTest() {}
281 virtual std::vector<LibraryEntry> SetUpLibrary() OVERRIDE {
282 base::FilePath track = library_dir().AppendASCII("Track.mp3");
283 std::vector<LibraryEntry> entries;
284 entries.push_back(LibraryEntry("Artist", "Album", track));
285 return entries;
288 virtual void StartTest(bool parse_success) OVERRIDE {
289 EXPECT_TRUE(parse_success);
291 // Initial contents.
292 ExpectTrackLocation("Artist", "Album", "Track.mp3");
293 ExpectNoTrack("Artist2", "Album2", "Track2.mp3");
295 // New file.
296 base::FilePath track2 = library_dir().AppendASCII("Track2.mp3");
297 std::vector<LibraryEntry> entries;
298 entries.push_back(LibraryEntry("Artist2", "Album2", track2));
299 WriteLibrary(entries,
300 base::Bind(&ITunesDataProviderRefreshTest::CheckAfterWrite,
301 base::Unretained(this)));
304 void CheckAfterWrite() {
305 // Content the same.
306 ExpectTrackLocation("Artist", "Album", "Track.mp3");
307 ExpectNoTrack("Artist2", "Album2", "Track2.mp3");
309 data_provider()->RefreshData(
310 base::Bind(&ITunesDataProviderRefreshTest::CheckRefresh,
311 base::Unretained(this)));
314 void CheckRefresh(bool is_valid) {
315 EXPECT_TRUE(is_valid);
317 ExpectTrackLocation("Artist2", "Album2", "Track2.mp3");
318 ExpectNoTrack("Artist", "Album", "Track.mp3");
319 TestDone();
322 private:
323 DISALLOW_COPY_AND_ASSIGN(ITunesDataProviderRefreshTest);
326 class ITunesDataProviderInvalidTest : public ITunesDataProviderTest {
327 public:
328 ITunesDataProviderInvalidTest() {}
329 virtual ~ITunesDataProviderInvalidTest() {}
331 virtual std::vector<LibraryEntry> SetUpLibrary() OVERRIDE {
332 base::FilePath track = library_dir().AppendASCII("Track.mp3");
333 std::vector<LibraryEntry> entries;
334 entries.push_back(LibraryEntry("Artist", "Album", track));
335 return entries;
338 virtual void StartTest(bool parse_success) OVERRIDE {
339 EXPECT_TRUE(parse_success);
341 SetLibraryChangeCallback(
342 base::Bind(&ITunesDataProvider::RefreshData,
343 base::Unretained(data_provider()),
344 base::Bind(&ITunesDataProviderInvalidTest::CheckInvalid,
345 base::Unretained(this))));
346 ASSERT_EQ(1L, file_util::WriteFile(XmlFile(), " ", 1));
349 void CheckInvalid(bool is_valid) {
350 EXPECT_FALSE(is_valid);
351 TestDone();
354 private:
355 DISALLOW_COPY_AND_ASSIGN(ITunesDataProviderInvalidTest);
358 class ITunesDataProviderUniqueNameTest : public ITunesDataProviderTest {
359 public:
360 ITunesDataProviderUniqueNameTest() {}
361 virtual ~ITunesDataProviderUniqueNameTest() {}
363 virtual std::vector<LibraryEntry> SetUpLibrary() OVERRIDE {
364 base::FilePath track = library_dir().AppendASCII("Track.mp3");
365 std::vector<LibraryEntry> entries;
366 // Dupe album names should get uniquified with the track id, which in the
367 // test framework is the vector index.
368 entries.push_back(LibraryEntry("Artist", "Album", track));
369 entries.push_back(LibraryEntry("Artist", "Album", track));
370 entries.push_back(LibraryEntry("Artist", "Album2", track));
371 return entries;
374 virtual void StartTest(bool parse_success) OVERRIDE {
375 EXPECT_TRUE(parse_success);
377 base::FilePath track =
378 library_dir().AppendASCII("Track.mp3").NormalizePathSeparators();
379 EXPECT_EQ(track.value(),
380 data_provider()->GetTrackLocation(
381 "Artist", "Album",
382 "Track (1).mp3").NormalizePathSeparators().value());
383 EXPECT_EQ(track.value(),
384 data_provider()->GetTrackLocation(
385 "Artist", "Album",
386 "Track (2).mp3").NormalizePathSeparators().value());
387 EXPECT_EQ(track.value(),
388 data_provider()->GetTrackLocation(
389 "Artist", "Album2",
390 "Track.mp3").NormalizePathSeparators().value());
392 TestDone();
395 private:
396 DISALLOW_COPY_AND_ASSIGN(ITunesDataProviderUniqueNameTest);
399 class ITunesDataProviderEscapeTest : public ITunesDataProviderTest {
400 // Albums and tracks that aren't the same, but become the same after
401 // replacing bad characters are not handled properly, but that case should
402 // never happen in practice.
403 public:
404 ITunesDataProviderEscapeTest() {}
405 virtual ~ITunesDataProviderEscapeTest() {}
407 virtual std::vector<LibraryEntry> SetUpLibrary() OVERRIDE {
408 base::FilePath track = library_dir().AppendASCII("Track:1.mp3");
409 std::vector<LibraryEntry> entries;
410 entries.push_back(LibraryEntry("Artist:/name", "Album:name/", track));
411 entries.push_back(LibraryEntry("Artist/name", "Album:name", track));
412 entries.push_back(LibraryEntry("Artist/name", "Album:name", track));
413 return entries;
416 virtual void StartTest(bool parse_success) OVERRIDE {
417 EXPECT_TRUE(parse_success);
419 base::FilePath track =
420 library_dir().AppendASCII("Track:1.mp3").NormalizePathSeparators();
421 EXPECT_EQ(track.value(),
422 data_provider()->GetTrackLocation(
423 "Artist__name", "Album_name_",
424 "Track_1.mp3").NormalizePathSeparators().value());
425 EXPECT_EQ(track.value(),
426 data_provider()->GetTrackLocation(
427 "Artist_name", "Album_name",
428 "Track_1 (2).mp3").NormalizePathSeparators().value());
429 EXPECT_EQ(track.value(),
430 data_provider()->GetTrackLocation(
431 "Artist_name", "Album_name",
432 "Track_1 (3).mp3").NormalizePathSeparators().value());
434 TestDone();
437 private:
438 DISALLOW_COPY_AND_ASSIGN(ITunesDataProviderEscapeTest);
441 IN_PROC_BROWSER_TEST_F(ITunesDataProviderBasicTest, BasicTest) {
442 RunTest();
445 IN_PROC_BROWSER_TEST_F(ITunesDataProviderRefreshTest, RefreshTest) {
446 RunTest();
449 IN_PROC_BROWSER_TEST_F(ITunesDataProviderInvalidTest, InvalidTest) {
450 RunTest();
453 IN_PROC_BROWSER_TEST_F(ITunesDataProviderUniqueNameTest, UniqueNameTest) {
454 RunTest();
457 IN_PROC_BROWSER_TEST_F(ITunesDataProviderEscapeTest, EscapeTest) {
458 RunTest();
461 } // namespace itunes