Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(359)

Side by Side Diff: chrome/browser/media_galleries/fileapi/itunes_data_provider_browsertest.cc

Issue 18348019: Add a test for ITunesDataProvider (try two). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rework Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698