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_backend.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 "url/gurl.h" | |
23 | |
24 using chrome::MediaFileSystemBackend; | |
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: | |
Lei Zhang
2013/07/17 02:21:35
None of this actually needs to be public.
vandebo (ex-Chrome)
2013/07/17 04:22:18
Done.
| |
67 ITunesDataProviderTest() {} | |
68 virtual ~ITunesDataProviderTest() {} | |
69 | |
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 chrome::ImportedMediaGalleryRegistry::GetInstance(); | |
78 InProcessBrowserTest::SetUp(); | |
79 } | |
80 | |
81 void RunTestOnMediaTaskRunner() { | |
Lei Zhang
2013/07/17 02:21:35
How about just RunTest(). RunTestOnMediaTaskRunner
vandebo (ex-Chrome)
2013/07/17 04:22:18
Done.
| |
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(); | |
90 } | |
91 | |
92 void WriteLibrary(const std::vector<LibraryEntry>& entries, | |
93 const base::Closure& callback) { | |
94 SetLibraryChangeCallback(callback); | |
95 WriteLibraryInternal(entries); | |
96 } | |
97 | |
98 void SetLibraryChangeCallback(const base::Closure& callback) { | |
99 EXPECT_TRUE(library_changed_callback_.is_null()); | |
100 library_changed_callback_ = callback; | |
101 } | |
102 | |
103 ITunesDataProvider* data_provider() const { | |
104 return chrome::ImportedMediaGalleryRegistry::ITunesDataProvider(); | |
105 } | |
106 | |
107 base::FilePath library_dir() const { | |
Lei Zhang
2013/07/17 02:21:35
This can return a const base::FilePath&
vandebo (ex-Chrome)
2013/07/17 04:22:18
Done.
| |
108 return library_dir_.path(); | |
109 } | |
110 | |
111 base::FilePath XmlFile() const { | |
112 return library_dir_.path().AppendASCII("library.xml"); | |
113 } | |
114 | |
115 protected: | |
116 // Get the initial set of library entries, called by SetUp. If no entries | |
117 // are returned the xml file is not created. | |
118 virtual std::vector<LibraryEntry> SetUpLibrary() { | |
119 return std::vector<LibraryEntry>(); | |
120 } | |
121 | |
122 // Start the test. The data provider is refreshed before calling StartTest | |
123 // and the result of the refresh is passed in. | |
124 virtual void StartTest(bool parse_success) = 0; | |
125 | |
126 void TestDone() { | |
Lei Zhang
2013/07/17 02:21:35
make sure you are on the MTR.
vandebo (ex-Chrome)
2013/07/17 04:22:18
Done.
| |
127 chrome::ImportedMediaGalleryRegistry* imported_registry = | |
128 chrome::ImportedMediaGalleryRegistry::GetInstance(); | |
129 imported_registry->itunes_data_provider_.reset(); | |
130 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, | |
131 quit_closure_); | |
132 } | |
133 | |
134 private: | |
135 void StartTestOnMediaTaskRunner() { | |
Lei Zhang
2013/07/17 02:21:35
Check you are on the MTR.
vandebo (ex-Chrome)
2013/07/17 04:22:18
Done.
| |
136 chrome::ImportedMediaGalleryRegistry* imported_registry = | |
137 chrome::ImportedMediaGalleryRegistry::GetInstance(); | |
138 imported_registry->itunes_data_provider_.reset( | |
139 new TestITunesDataProvider( | |
140 XmlFile(), | |
141 base::Bind(&ITunesDataProviderTest::OnLibraryChanged, | |
142 base::Unretained(this)))); | |
143 data_provider()->RefreshData(base::Bind(&ITunesDataProviderTest::StartTest, | |
144 base::Unretained(this))); | |
145 }; | |
146 | |
147 void OnLibraryChanged(void) { | |
Lei Zhang
2013/07/17 02:21:35
nit: We usually don't write (void). Same on line 2
vandebo (ex-Chrome)
2013/07/17 04:22:18
Done.
| |
148 DCHECK( | |
149 MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread()); | |
Lei Zhang
2013/07/17 02:21:35
nit: fits on previous line.
vandebo (ex-Chrome)
2013/07/17 04:22:18
Done.
| |
150 if (!library_changed_callback_.is_null()) { | |
151 library_changed_callback_.Run(); | |
152 library_changed_callback_.Reset(); | |
153 } | |
154 } | |
155 | |
156 void WriteLibraryInternal(const std::vector<LibraryEntry>& entries) { | |
157 if (!entries.size()) | |
158 return; | |
159 std::string xml = "<plist><dict><key>Tracks</key><dict>\n"; | |
160 for (size_t i = 0; i < entries.size(); ++i) { | |
161 GURL location("file://localhost/" + entries[i].location.AsUTF8Unsafe()); | |
162 // Visual studio doesn't like %zd, so cast to int instead. | |
Lei Zhang
2013/07/17 02:21:35
Look for PRIuS in base/format_macros.h.
vandebo (ex-Chrome)
2013/07/17 04:22:18
Done.
| |
163 int id = static_cast<int>(i) + 1; | |
164 std::string entry_string = base::StringPrintf( | |
165 "<key>%d</key><dict>\n" | |
166 " <key>Track ID</key><integer>%d</integer>\n" | |
167 " <key>Location</key><string>%s</string>\n" | |
168 " <key>Artist</key><string>%s</string>\n" | |
169 " <key>Album</key><string>%s</string>\n" | |
170 "</dict>\n", | |
171 id, id, location.spec().c_str(), entries[i].artist.c_str(), | |
172 entries[i].album.c_str()); | |
173 xml += entry_string; | |
174 } | |
175 xml += "</dict></dict></plist>\n"; | |
176 file_util::WriteFile(XmlFile(), xml.c_str(), xml.size()); | |
Lei Zhang
2013/07/17 02:21:35
Make sure we wrote the right # of bytes. Ditto for
vandebo (ex-Chrome)
2013/07/17 04:22:18
Done.
| |
177 } | |
178 | |
179 base::ScopedTempDir library_dir_; | |
180 | |
181 base::Closure library_changed_callback_; | |
182 | |
183 base::Closure quit_closure_; | |
184 | |
185 DISALLOW_COPY_AND_ASSIGN(ITunesDataProviderTest); | |
186 }; | |
187 | |
188 class ITunesDataProviderBasicTest : public ITunesDataProviderTest { | |
189 public: | |
190 ITunesDataProviderBasicTest() {} | |
191 virtual ~ITunesDataProviderBasicTest() {} | |
192 | |
193 virtual std::vector<LibraryEntry> SetUpLibrary() OVERRIDE { | |
194 base::FilePath track = library_dir().AppendASCII("Track.mp3"); | |
195 std::vector<LibraryEntry> entries; | |
196 entries.push_back(LibraryEntry("Artist", "Album", track)); | |
197 return entries; | |
198 } | |
199 | |
200 virtual void StartTest(bool parse_success) OVERRIDE { | |
201 EXPECT_TRUE(parse_success); | |
202 | |
203 // KnownArtist | |
204 EXPECT_TRUE(data_provider()->KnownArtist("Artist")); | |
205 EXPECT_FALSE(data_provider()->KnownArtist("Artist2")); | |
206 | |
207 // KnownAlbum | |
208 EXPECT_TRUE(data_provider()->KnownAlbum("Artist", "Album")); | |
209 EXPECT_FALSE(data_provider()->KnownAlbum("Artist", "Album2")); | |
210 EXPECT_FALSE(data_provider()->KnownAlbum("Artist2", "Album")); | |
211 | |
212 // GetTrackLocation | |
213 base::FilePath track = | |
214 library_dir().AppendASCII("Track.mp3").NormalizePathSeparators(); | |
215 EXPECT_EQ(track.value(), | |
216 data_provider()->GetTrackLocation( | |
217 "Artist", "Album", | |
218 "Track.mp3").NormalizePathSeparators().value()); | |
219 EXPECT_TRUE(data_provider()->GetTrackLocation("Artist", "Album", | |
220 "Track2.mp3").empty()); | |
221 EXPECT_TRUE(data_provider()->GetTrackLocation("Artist", "Album2", | |
222 "Track.mp3").empty()); | |
223 EXPECT_TRUE(data_provider()->GetTrackLocation("Artist2", "Album", | |
224 "Track.mp3").empty()); | |
225 | |
226 // GetArtistNames | |
227 std::set<ITunesDataProvider::ArtistName> artists = | |
228 data_provider()->GetArtistNames(); | |
229 EXPECT_EQ(1U, artists.size()); | |
Lei Zhang
2013/07/17 02:21:35
This should be an ASSERT_EQ(), otherwise the next
vandebo (ex-Chrome)
2013/07/17 04:22:18
Done.
| |
230 EXPECT_EQ(std::string("Artist"), *artists.begin()); | |
Lei Zhang
2013/07/17 02:21:35
do you need the explicit std::string()? Ditto belo
vandebo (ex-Chrome)
2013/07/17 04:22:18
Done.
| |
231 | |
232 // GetAlbumNames | |
233 std::set<ITunesDataProvider::AlbumName> albums = | |
234 data_provider()->GetAlbumNames("Artist"); | |
235 EXPECT_EQ(1U, albums.size()); | |
236 EXPECT_EQ(std::string("Album"), *albums.begin()); | |
237 | |
238 albums = data_provider()->GetAlbumNames("Artist2"); | |
239 EXPECT_EQ(0U, albums.size()); | |
240 | |
241 // GetAlbum | |
242 ITunesDataProvider::Album album = | |
243 data_provider()->GetAlbum("Artist", "Album"); | |
244 EXPECT_EQ(1U, album.size()); | |
245 EXPECT_EQ(track.BaseName().AsUTF8Unsafe(), album.begin()->first); | |
246 EXPECT_EQ(track.value(), | |
247 album.begin()->second.NormalizePathSeparators().value()); | |
248 | |
249 album = data_provider()->GetAlbum("Artist", "Album2"); | |
250 EXPECT_EQ(0U, album.size()); | |
251 | |
252 album = data_provider()->GetAlbum("Artist2", "Album"); | |
253 EXPECT_EQ(0U, album.size()); | |
254 | |
255 TestDone(); | |
256 } | |
257 | |
258 private: | |
259 DISALLOW_COPY_AND_ASSIGN(ITunesDataProviderBasicTest); | |
260 }; | |
261 | |
262 class ITunesDataProviderRefreshTest : public ITunesDataProviderTest { | |
263 public: | |
264 ITunesDataProviderRefreshTest() {} | |
265 virtual ~ITunesDataProviderRefreshTest() {} | |
266 | |
267 virtual std::vector<LibraryEntry> SetUpLibrary() OVERRIDE { | |
268 base::FilePath track = library_dir().AppendASCII("Track.mp3"); | |
269 std::vector<LibraryEntry> entries; | |
270 entries.push_back(LibraryEntry("Artist", "Album", track)); | |
271 return entries; | |
272 } | |
273 | |
274 virtual void StartTest(bool parse_success) OVERRIDE { | |
275 EXPECT_TRUE(parse_success); | |
276 | |
277 // Initial contents. | |
278 ExpectTrackLocation("Artist", "Album", "Track.mp3"); | |
279 ExpectNoTrack("Artist2", "Album2", "Track2.mp3"); | |
280 | |
281 // New file. | |
282 base::FilePath track2 = library_dir().AppendASCII("Track2.mp3"); | |
283 std::vector<LibraryEntry> entries; | |
284 entries.push_back(LibraryEntry("Artist2", "Album2", track2)); | |
285 WriteLibrary(entries, | |
286 base::Bind(&ITunesDataProviderRefreshTest::CheckAfterWrite, | |
287 base::Unretained(this))); | |
288 } | |
289 | |
290 void CheckAfterWrite(void) { | |
291 // Content the same. | |
292 ExpectTrackLocation("Artist", "Album", "Track.mp3"); | |
293 ExpectNoTrack("Artist2", "Album2", "Track2.mp3"); | |
294 | |
295 data_provider()->RefreshData( | |
296 base::Bind(&ITunesDataProviderRefreshTest::CheckRefresh, | |
297 base::Unretained(this))); | |
298 } | |
299 | |
300 void CheckRefresh(bool is_valid) { | |
301 EXPECT_TRUE(is_valid); | |
302 | |
303 ExpectTrackLocation("Artist2", "Album2", "Track2.mp3"); | |
304 ExpectNoTrack("Artist", "Album", "Track.mp3"); | |
305 TestDone(); | |
306 } | |
307 | |
308 private: | |
309 void ExpectTrackLocation(const std::string& artist, const std::string& album, | |
Lei Zhang
2013/07/17 02:21:35
If you put this and ExpectNoTrack() in ITunesDataP
vandebo (ex-Chrome)
2013/07/17 04:22:18
Done.
| |
310 const std::string& track_name) { | |
311 base::FilePath track = | |
312 library_dir().AppendASCII(track_name).NormalizePathSeparators(); | |
313 EXPECT_EQ(track.value(), | |
314 data_provider()->GetTrackLocation( | |
315 artist, album, track_name).NormalizePathSeparators().value()); | |
316 } | |
317 | |
318 void ExpectNoTrack(const std::string& artist, const std::string& album, | |
319 const std::string& track_name) { | |
320 EXPECT_TRUE(data_provider()->GetTrackLocation( | |
321 artist, album, track_name).empty()) << track_name; | |
322 } | |
323 | |
324 DISALLOW_COPY_AND_ASSIGN(ITunesDataProviderRefreshTest); | |
325 }; | |
326 | |
327 class ITunesDataProviderInvalidTest : public ITunesDataProviderTest { | |
328 public: | |
329 ITunesDataProviderInvalidTest() {} | |
330 virtual ~ITunesDataProviderInvalidTest() {} | |
331 | |
332 virtual std::vector<LibraryEntry> SetUpLibrary() OVERRIDE { | |
333 base::FilePath track = library_dir().AppendASCII("Track.mp3"); | |
334 std::vector<LibraryEntry> entries; | |
335 entries.push_back(LibraryEntry("Artist", "Album", track)); | |
336 return entries; | |
337 } | |
338 | |
339 virtual void StartTest(bool parse_success) OVERRIDE { | |
340 EXPECT_TRUE(parse_success); | |
341 | |
342 SetLibraryChangeCallback( | |
343 base::Bind(&ITunesDataProvider::RefreshData, | |
344 base::Unretained(data_provider()), | |
345 base::Bind(&ITunesDataProviderInvalidTest::CheckInvalid, | |
346 base::Unretained(this)))); | |
347 file_util::WriteFile(XmlFile(), " ", 1); | |
348 } | |
349 | |
350 void CheckInvalid(bool is_valid) { | |
351 EXPECT_FALSE(is_valid); | |
352 TestDone(); | |
353 } | |
354 | |
355 private: | |
356 DISALLOW_COPY_AND_ASSIGN(ITunesDataProviderInvalidTest); | |
357 }; | |
358 | |
359 class ITunesDataProviderUniqueNameTest : public ITunesDataProviderTest { | |
360 public: | |
361 ITunesDataProviderUniqueNameTest() {} | |
362 virtual ~ITunesDataProviderUniqueNameTest() {} | |
363 | |
364 virtual std::vector<LibraryEntry> SetUpLibrary() OVERRIDE { | |
365 base::FilePath track = library_dir().AppendASCII("Track.mp3"); | |
366 std::vector<LibraryEntry> entries; | |
367 // Dupe album names should get uniquified with the track id, which in the | |
368 // test framework is the vector index. | |
369 entries.push_back(LibraryEntry("Artist", "Album", track)); | |
370 entries.push_back(LibraryEntry("Artist", "Album", track)); | |
371 entries.push_back(LibraryEntry("Artist", "Album2", track)); | |
372 return entries; | |
373 } | |
374 | |
375 virtual void StartTest(bool parse_success) OVERRIDE { | |
376 EXPECT_TRUE(parse_success); | |
377 | |
378 base::FilePath track = | |
379 library_dir().AppendASCII("Track.mp3").NormalizePathSeparators(); | |
380 EXPECT_EQ(track.value(), | |
381 data_provider()->GetTrackLocation( | |
382 "Artist", "Album", | |
383 "Track (1).mp3").NormalizePathSeparators().value()); | |
384 EXPECT_EQ(track.value(), | |
385 data_provider()->GetTrackLocation( | |
386 "Artist", "Album", | |
387 "Track (2).mp3").NormalizePathSeparators().value()); | |
388 EXPECT_EQ(track.value(), | |
389 data_provider()->GetTrackLocation( | |
390 "Artist", "Album2", | |
391 "Track.mp3").NormalizePathSeparators().value()); | |
392 | |
393 TestDone(); | |
394 } | |
395 | |
396 private: | |
397 DISALLOW_COPY_AND_ASSIGN(ITunesDataProviderUniqueNameTest); | |
398 }; | |
399 | |
400 IN_PROC_BROWSER_TEST_F(ITunesDataProviderBasicTest, BasicTest) { | |
401 RunTestOnMediaTaskRunner(); | |
402 } | |
403 | |
404 IN_PROC_BROWSER_TEST_F(ITunesDataProviderRefreshTest, RefreshTest) { | |
405 RunTestOnMediaTaskRunner(); | |
406 } | |
407 | |
408 IN_PROC_BROWSER_TEST_F(ITunesDataProviderInvalidTest, InvalidTest) { | |
409 RunTestOnMediaTaskRunner(); | |
410 } | |
411 | |
412 IN_PROC_BROWSER_TEST_F(ITunesDataProviderUniqueNameTest, UniqueNameTest) { | |
413 RunTestOnMediaTaskRunner(); | |
414 } | |
415 | |
416 } // namespace itunes | |
OLD | NEW |