OLD | NEW |
---|---|
(Empty) | |
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/file_util.h" | |
10 #include "base/files/file_path.h" | |
11 #include "base/files/scoped_temp_dir.h" | |
12 #include "base/logging.h" | |
13 #include "base/memory/scoped_ptr.h" | |
14 #include "base/message_loop.h" | |
15 #include "base/run_loop.h" | |
16 #include "base/strings/stringprintf.h" | |
17 #include "chrome/browser/media_galleries/fileapi/itunes_data_provider.h" | |
18 #include "chrome/browser/media_galleries/fileapi/media_file_system_mount_point_p rovider.h" | |
19 #include "chrome/browser/media_galleries/imported_media_gallery_registry.h" | |
20 #include "chrome/test/base/in_process_browser_test.h" | |
21 #include "content/public/browser/browser_thread.h" | |
22 #include "googleurl/src/gurl.h" | |
23 | |
24 using chrome::MediaFileSystemMountPointProvider; | |
25 | |
26 namespace itunes { | |
27 | |
28 namespace { | |
29 | |
30 struct LibraryEntry { | |
31 LibraryEntry(const std::string& artist, const std::string& album, | |
32 const base::FilePath& location) | |
33 : artist(artist), | |
34 album(album), | |
35 location(location) { | |
36 } | |
37 std::string artist; | |
38 std::string album; | |
39 base::FilePath location; | |
40 }; | |
41 | |
42 } // namespace | |
43 | |
44 class TestITunesDataProvider : public ITunesDataProvider { | |
45 public: | |
46 TestITunesDataProvider(const base::FilePath& xml_library_path, | |
47 const base::Closure& callback) | |
48 : ITunesDataProvider(xml_library_path), | |
49 callback_(callback) { | |
50 } | |
51 virtual ~TestITunesDataProvider() {} | |
52 | |
53 private: | |
54 virtual void OnLibraryChanged(const base::FilePath& path, | |
55 bool error) OVERRIDE { | |
56 ITunesDataProvider::OnLibraryChanged(path, error); | |
57 callback_.Run(); | |
58 } | |
59 | |
60 base::Closure callback_; | |
61 | |
62 DISALLOW_COPY_AND_ASSIGN(TestITunesDataProvider); | |
63 }; | |
64 | |
65 class ITunesDataProviderTest : public InProcessBrowserTest { | |
66 public: | |
67 ITunesDataProviderTest() {} | |
68 virtual ~ITunesDataProviderTest() {} | |
69 | |
70 virtual void SetUp() OVERRIDE { | |
71 ASSERT_TRUE(library_dir_.CreateUniqueTempDir()); | |
72 // The ImportedMediaGalleryRegistry is created on which ever thread calls | |
73 // GetInstance() first. It shouldn't matter what thread creates, however | |
74 // in practice it is always created on the UI thread, so this calls | |
75 // GetInstance here to mirror those real conditions. | |
76 chrome::ImportedMediaGalleryRegistry::GetInstance(); | |
77 InProcessBrowserTest::SetUp(); | |
78 } | |
79 | |
80 void RunTestOnMediaTaskRunner() { | |
81 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
82 base::RunLoop loop; | |
83 quit_closure_ = loop.QuitClosure(); | |
84 MediaFileSystemMountPointProvider::MediaTaskRunner()->PostTask( | |
85 FROM_HERE, | |
86 base::Bind(&ITunesDataProviderTest::StartTestOnMediaTaskRunner, | |
87 base::Unretained(this))); | |
88 loop.Run(); | |
89 } | |
90 | |
91 void WriteLibraryAndRefresh( | |
92 const std::vector<LibraryEntry>& entries, | |
93 const ITunesDataProvider::ReadyCallback& callback) { | |
94 WriteLibrary(entries, base::Bind(&ITunesDataProviderTest::RefreshData, | |
95 base::Unretained(this), callback)); | |
96 } | |
97 | |
98 void WriteLibrary(const std::vector<LibraryEntry>& entries, | |
99 const base::Closure& callback) { | |
100 std::string xml = "<plist><dict><key>Tracks</key><dict>\n"; | |
101 for (size_t i = 0; i < entries.size(); ++i) { | |
102 GURL location("file://localhost/" + entries[i].location.AsUTF8Unsafe()); | |
103 // Visual studio doesn't like %zd, so cast to int instead. | |
104 int id = static_cast<int>(i) + 1; | |
105 std::string entry_string = base::StringPrintf( | |
106 "<key>%d</key><dict>\n" | |
107 " <key>Track ID</key><integer>%d</integer>\n" | |
108 " <key>Location</key><string>%s</string>\n" | |
109 " <key>Album Artist</key><string>%s</string>\n" | |
Lei Zhang
2013/07/16 22:03:25
Don't forget to update this as a result of the Art
vandebo (ex-Chrome)
2013/07/16 23:07:04
Done.
| |
110 " <key>Album</key><string>%s</string>\n" | |
111 "</dict>\n", | |
112 id, id, location.spec().c_str(), entries[i].artist.c_str(), | |
113 entries[i].album.c_str()); | |
114 xml += entry_string; | |
115 } | |
116 xml += "</dict></dict></plist>\n"; | |
117 file_util::WriteFile(XmlFile(), xml.c_str(), xml.size()); | |
118 | |
119 EXPECT_TRUE(library_changed_callback_.is_null()); | |
120 library_changed_callback_ = callback; | |
121 } | |
122 | |
123 void RefreshData(const ITunesDataProvider::ReadyCallback& callback) const { | |
124 data_provider()->RefreshData(callback); | |
125 } | |
126 | |
127 ITunesDataProvider* data_provider() const { | |
128 return chrome::ImportedMediaGalleryRegistry::ITunesDataProvider(); | |
129 } | |
130 | |
131 base::FilePath library_dir() const { | |
132 return library_dir_.path(); | |
133 } | |
134 | |
135 base::FilePath XmlFile() const { | |
136 return library_dir_.path().AppendASCII("library.xml"); | |
137 } | |
138 | |
139 protected: | |
140 virtual void StartTest() = 0; | |
141 | |
142 void TestDone() { | |
143 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, | |
144 quit_closure_); | |
145 } | |
146 | |
147 private: | |
148 void StartTestOnMediaTaskRunner() { | |
149 chrome::ImportedMediaGalleryRegistry* imported_registry = | |
150 chrome::ImportedMediaGalleryRegistry::GetInstance(); | |
151 imported_registry->itunes_data_provider_.reset( | |
152 new TestITunesDataProvider( | |
153 XmlFile(), | |
154 base::Bind(&ITunesDataProviderTest::OnLibraryChanged, | |
155 base::Unretained(this)))); | |
156 StartTest(); | |
157 imported_registry->itunes_data_provider_.reset(); | |
158 }; | |
159 | |
160 void OnLibraryChanged(void) { | |
161 DCHECK( | |
162 MediaFileSystemMountPointProvider::CurrentlyOnMediaTaskRunnerThread()); | |
163 EXPECT_FALSE(library_changed_callback_.is_null()); | |
164 library_changed_callback_.Run(); | |
165 library_changed_callback_.Reset(); | |
166 } | |
167 | |
168 base::ScopedTempDir library_dir_; | |
169 | |
170 base::Closure library_changed_callback_; | |
171 | |
172 base::Closure quit_closure_; | |
173 | |
174 DISALLOW_COPY_AND_ASSIGN(ITunesDataProviderTest); | |
175 }; | |
176 | |
177 class ITunesDataProviderBasicTest : public ITunesDataProviderTest { | |
178 public: | |
179 ITunesDataProviderBasicTest() {} | |
180 virtual ~ITunesDataProviderBasicTest() {} | |
181 | |
182 virtual void StartTest() OVERRIDE { | |
183 base::FilePath track = library_dir().AppendASCII("Track.mp3"); | |
184 std::vector<LibraryEntry> entries; | |
185 entries.push_back(LibraryEntry("Artist", "Album", track)); | |
186 | |
187 WriteLibraryAndRefresh(entries, | |
188 base::Bind(&ITunesDataProviderBasicTest::CheckData, | |
189 base::Unretained(this))); | |
190 } | |
191 | |
192 void CheckData(bool is_valid) { | |
193 EXPECT_TRUE(is_valid); | |
194 | |
195 // KnownArtist | |
196 EXPECT_TRUE(data_provider()->KnownArtist("Artist")); | |
197 EXPECT_FALSE(data_provider()->KnownArtist("Artist2")); | |
198 | |
199 // KnownAlbum | |
200 EXPECT_TRUE(data_provider()->KnownAlbum("Artist", "Album")); | |
201 EXPECT_FALSE(data_provider()->KnownAlbum("Artist", "Album2")); | |
202 EXPECT_FALSE(data_provider()->KnownAlbum("Artist2", "Album")); | |
203 | |
204 // GetTrackLocation | |
205 base::FilePath track = | |
206 library_dir().AppendASCII("Track.mp3").NormalizePathSeparators(); | |
207 EXPECT_EQ(track.value(), | |
208 data_provider()->GetTrackLocation( | |
209 "Artist", "Album", | |
210 "Track.mp3").NormalizePathSeparators().value()); | |
211 EXPECT_TRUE(data_provider()->GetTrackLocation("Artist", "Album", | |
212 "Track2.mp3").empty()); | |
213 EXPECT_TRUE(data_provider()->GetTrackLocation("Artist", "Album2", | |
214 "Track.mp3").empty()); | |
215 EXPECT_TRUE(data_provider()->GetTrackLocation("Artist2", "Album", | |
216 "Track.mp3").empty()); | |
217 | |
218 // GetArtistNames | |
219 std::set<ITunesDataProvider::ArtistName> artists = | |
220 data_provider()->GetArtistNames(); | |
221 EXPECT_EQ(1U, artists.size()); | |
222 EXPECT_EQ(std::string("Artist"), *artists.begin()); | |
223 | |
224 // GetAlbumNames | |
225 std::set<ITunesDataProvider::AlbumName> albums = | |
226 data_provider()->GetAlbumNames("Artist"); | |
227 EXPECT_EQ(1U, albums.size()); | |
228 EXPECT_EQ(std::string("Album"), *albums.begin()); | |
229 | |
230 albums = data_provider()->GetAlbumNames("Artist2"); | |
231 EXPECT_EQ(0U, albums.size()); | |
232 | |
233 // GetAlbum | |
234 ITunesDataProvider::Album album = | |
235 data_provider()->GetAlbum("Artist", "Album"); | |
236 EXPECT_EQ(1U, album.size()); | |
237 EXPECT_EQ(track.BaseName().AsUTF8Unsafe(), album.begin()->first); | |
238 EXPECT_EQ(track.value(), | |
239 album.begin()->second.NormalizePathSeparators().value()); | |
240 | |
241 album = data_provider()->GetAlbum("Artist", "Album2"); | |
242 EXPECT_EQ(0U, album.size()); | |
243 | |
244 album = data_provider()->GetAlbum("Artist2", "Album"); | |
245 EXPECT_EQ(0U, album.size()); | |
246 | |
247 TestDone(); | |
248 } | |
249 | |
250 private: | |
251 DISALLOW_COPY_AND_ASSIGN(ITunesDataProviderBasicTest); | |
252 }; | |
253 | |
254 class ITunesDataProviderRefreshTest : public ITunesDataProviderTest { | |
255 public: | |
256 ITunesDataProviderRefreshTest() {} | |
257 virtual ~ITunesDataProviderRefreshTest() {} | |
258 | |
259 virtual void StartTest() OVERRIDE { | |
260 base::FilePath track = library_dir().AppendASCII("Track.mp3"); | |
261 std::vector<LibraryEntry> entries; | |
262 entries.push_back(LibraryEntry("Artist", "Album", track)); | |
263 | |
264 WriteLibraryAndRefresh(entries, | |
265 base::Bind(&ITunesDataProviderRefreshTest::CheckData, | |
266 base::Unretained(this))); | |
267 } | |
268 | |
269 void CheckData(bool is_valid) { | |
270 EXPECT_TRUE(is_valid); | |
271 | |
272 // Initial contents. | |
273 ExpectTrackLocation("Artist", "Album", "Track.mp3"); | |
274 ExpectNoTrack("Artist2", "Album2", "Track2.mp3"); | |
275 | |
276 // New file. | |
277 base::FilePath track2 = library_dir().AppendASCII("Track2.mp3"); | |
278 std::vector<LibraryEntry> entries; | |
279 entries.push_back(LibraryEntry("Artist2", "Album2", track2)); | |
280 WriteLibrary(entries, | |
281 base::Bind(&ITunesDataProviderRefreshTest::CheckAfterWrite, | |
282 base::Unretained(this))); | |
283 } | |
284 | |
285 void CheckAfterWrite(void) { | |
286 // Content the same. | |
287 ExpectTrackLocation("Artist", "Album", "Track.mp3"); | |
288 ExpectNoTrack("Artist2", "Album2", "Track2.mp3"); | |
289 | |
290 RefreshData(base::Bind(&ITunesDataProviderRefreshTest::CheckRefresh, | |
291 base::Unretained(this))); | |
292 } | |
293 | |
294 void CheckRefresh(bool is_valid) { | |
295 EXPECT_TRUE(is_valid); | |
296 | |
297 ExpectTrackLocation("Artist2", "Album2", "Track2.mp3"); | |
298 ExpectNoTrack("Artist", "Album", "Track.mp3"); | |
299 | |
300 file_util::WriteFile(XmlFile(), " ", 1); | |
301 | |
302 ExpectTrackLocation("Artist2", "Album2", "Track2.mp3"); | |
303 ExpectNoTrack("Artist", "Album", "Track.mp3"); | |
304 | |
305 RefreshData(base::Bind(&ITunesDataProviderRefreshTest::CheckInvalid, | |
306 base::Unretained(this))); | |
307 } | |
308 | |
309 void CheckInvalid(bool is_valid) { | |
310 EXPECT_FALSE(is_valid); | |
311 TestDone(); | |
312 } | |
313 | |
314 private: | |
315 void ExpectTrackLocation(const std::string& artist, const std::string& album, | |
316 const std::string& track_name) { | |
317 base::FilePath track = | |
318 library_dir().AppendASCII(track_name).NormalizePathSeparators(); | |
319 EXPECT_EQ(track.value(), | |
320 data_provider()->GetTrackLocation( | |
321 artist, album, track_name).NormalizePathSeparators().value()); | |
322 } | |
323 | |
324 void ExpectNoTrack(const std::string& artist, const std::string& album, | |
325 const std::string& track_name) { | |
326 EXPECT_TRUE(data_provider()->GetTrackLocation( | |
327 artist, album, track_name).empty()) << track_name; | |
328 } | |
329 | |
330 DISALLOW_COPY_AND_ASSIGN(ITunesDataProviderRefreshTest); | |
331 }; | |
332 | |
333 class ITunesDataProviderUniqueNameTest : public ITunesDataProviderTest { | |
334 public: | |
335 ITunesDataProviderUniqueNameTest() {} | |
336 virtual ~ITunesDataProviderUniqueNameTest() {} | |
337 | |
338 virtual void StartTest() OVERRIDE { | |
339 base::FilePath track = library_dir().AppendASCII("Track.mp3"); | |
340 std::vector<LibraryEntry> entries; | |
341 // Dupe album names should get uniquified with the track id, which in the | |
342 // test framework is the vector index. | |
343 entries.push_back(LibraryEntry("Artist", "Album", track)); | |
344 entries.push_back(LibraryEntry("Artist", "Album", track)); | |
345 entries.push_back(LibraryEntry("Artist", "Album2", track)); | |
346 | |
347 WriteLibraryAndRefresh( | |
348 entries, | |
349 base::Bind(&ITunesDataProviderUniqueNameTest::CheckData, | |
350 base::Unretained(this))); | |
351 } | |
352 | |
353 void CheckData(bool is_valid) { | |
354 EXPECT_TRUE(is_valid); | |
355 | |
356 base::FilePath track = | |
357 library_dir().AppendASCII("Track.mp3").NormalizePathSeparators(); | |
358 EXPECT_EQ(track.value(), | |
359 data_provider()->GetTrackLocation( | |
360 "Artist", "Album", | |
361 "Track (1).mp3").NormalizePathSeparators().value()); | |
362 EXPECT_EQ(track.value(), | |
363 data_provider()->GetTrackLocation( | |
364 "Artist", "Album", | |
365 "Track (2).mp3").NormalizePathSeparators().value()); | |
366 EXPECT_EQ(track.value(), | |
367 data_provider()->GetTrackLocation( | |
368 "Artist", "Album2", | |
369 "Track.mp3").NormalizePathSeparators().value()); | |
370 | |
371 TestDone(); | |
372 } | |
373 | |
374 private: | |
375 DISALLOW_COPY_AND_ASSIGN(ITunesDataProviderUniqueNameTest); | |
376 }; | |
377 | |
378 IN_PROC_BROWSER_TEST_F(ITunesDataProviderBasicTest, BasicTest) { | |
379 RunTestOnMediaTaskRunner(); | |
380 } | |
381 | |
382 IN_PROC_BROWSER_TEST_F(ITunesDataProviderRefreshTest, RefreshTest) { | |
383 RunTestOnMediaTaskRunner(); | |
384 } | |
385 | |
386 IN_PROC_BROWSER_TEST_F(ITunesDataProviderUniqueNameTest, UniqueNameTest) { | |
387 RunTestOnMediaTaskRunner(); | |
388 } | |
389 | |
390 } // namespace itunes | |
OLD | NEW |