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 ITunesDataProviderTest : public InProcessBrowserTest { | |
45 public: | |
46 ITunesDataProviderTest() {} | |
47 virtual ~ITunesDataProviderTest() {} | |
48 | |
49 virtual void SetUp() OVERRIDE { | |
50 ASSERT_TRUE(library_dir_.CreateUniqueTempDir()); | |
51 InProcessBrowserTest::SetUp(); | |
52 } | |
53 | |
54 void RunTestOnMediaTaskRunner() { | |
55 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
56 | |
57 chrome::ImportedMediaGalleryRegistry* imported_registry = | |
58 chrome::ImportedMediaGalleryRegistry::GetInstance(); | |
59 std::string itunes_fsid = | |
60 imported_registry->RegisterITunesFilesystemOnUIThread(XmlFile()); | |
61 | |
62 base::RunLoop loop; | |
63 quit_closure_ = loop.QuitClosure(); | |
64 MediaFileSystemMountPointProvider::MediaTaskRunner()->PostTask( | |
65 FROM_HERE, base::Bind(&ITunesDataProviderTest::StartTest, | |
66 base::Unretained(this))); | |
67 loop.Run(); | |
68 | |
69 imported_registry->RevokeImportedFilesystemOnUIThread(itunes_fsid); | |
70 } | |
71 | |
72 void WriteLibrary(const std::vector<LibraryEntry>& entries) { | |
73 std::string xml = "<plist><dict><key>Tracks</key><dict>\n"; | |
74 for (size_t i = 0; i < entries.size(); ++i) { | |
75 GURL location("file://localhost/" + entries[i].location.AsUTF8Unsafe()); | |
76 // Visual studio doesn't like %zd, so cast to int instead. | |
77 int id = static_cast<int>(i) + 1; | |
Greg Billock
2013/07/02 20:29:57
ids of zero bad? How about making i=1; i <= entrie
vandebo (ex-Chrome)
2013/07/02 21:00:31
Not bad, just edgecase-y. I can't change the loop
| |
78 std::string entry_string = base::StringPrintf( | |
79 "<key>%d</key><dict>\n" | |
80 " <key>Track ID</key><integer>%d</integer>\n" | |
81 " <key>Location</key><string>%s</string>\n" | |
82 " <key>Album Artist</key><string>%s</string>\n" | |
83 " <key>Album</key><string>%s</string>\n" | |
84 "</dict>\n", | |
85 id, id, location.spec().c_str(), entries[i].artist.c_str(), | |
86 entries[i].album.c_str()); | |
87 xml += entry_string; | |
88 } | |
89 xml += "</dict></dict></plist>\n"; | |
90 | |
91 base::FilePath library_file = | |
92 library_dir_.path().AppendASCII("library.xml"); | |
Greg Billock
2013/07/02 20:29:57
use XmlFile() here.
vandebo (ex-Chrome)
2013/07/02 21:00:31
Oops, done.
| |
93 file_util::WriteFile(library_file, xml.c_str(), xml.size()); | |
94 } | |
95 | |
96 void RefreshData(const ITunesDataProvider::ReadyCallback& callback) { | |
Greg Billock
2013/07/02 20:29:57
Could this be made synchronous with a waitable eve
vandebo (ex-Chrome)
2013/07/02 21:00:31
I started with a RunLoop, but that doesn't work on
| |
97 data_provider()->RefreshData(callback); | |
98 } | |
99 | |
100 ITunesDataProvider* data_provider() { | |
101 return chrome::ImportedMediaGalleryRegistry::ITunesDataProvider(); | |
102 } | |
103 | |
104 base::FilePath library_dir() { | |
105 return library_dir_.path(); | |
106 } | |
107 | |
108 base::FilePath XmlFile() { | |
109 return library_dir_.path().AppendASCII("library.xml"); | |
110 } | |
111 | |
112 protected: | |
113 virtual void StartTest() = 0; | |
114 | |
115 void TestDone() { | |
116 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, | |
117 quit_closure_); | |
118 } | |
119 | |
120 private: | |
121 base::ScopedTempDir library_dir_; | |
122 | |
123 base::Closure quit_closure_; | |
124 | |
125 DISALLOW_COPY_AND_ASSIGN(ITunesDataProviderTest); | |
126 }; | |
127 | |
128 class ITunesDataProviderBasicTest : public ITunesDataProviderTest { | |
129 public: | |
130 ITunesDataProviderBasicTest() {} | |
131 virtual ~ITunesDataProviderBasicTest() {} | |
132 | |
133 void StartTest() { | |
134 base::FilePath track = library_dir().AppendASCII("Track.mp3"); | |
135 std::vector<LibraryEntry> entries; | |
136 entries.push_back(LibraryEntry("Artist", "Album", track)); | |
137 | |
138 WriteLibrary(entries); | |
139 RefreshData(base::Bind(&ITunesDataProviderBasicTest::CheckData, | |
140 base::Unretained(this))); | |
141 } | |
142 | |
143 void CheckData(bool is_valid) { | |
144 EXPECT_TRUE(is_valid); | |
145 | |
146 // KnownArtist | |
147 EXPECT_TRUE(data_provider()->KnownArtist("Artist")); | |
Greg Billock
2013/07/02 20:29:57
I don't see why these APIs exist. Shouldn't we jus
vandebo (ex-Chrome)
2013/07/02 21:00:31
If you look at where ITunesDataProvider is used, i
| |
148 EXPECT_FALSE(data_provider()->KnownArtist("Artist2")); | |
149 | |
150 // KnownAlbum | |
151 EXPECT_TRUE(data_provider()->KnownAlbum("Artist", "Album")); | |
152 EXPECT_FALSE(data_provider()->KnownAlbum("Artist", "Album2")); | |
153 EXPECT_FALSE(data_provider()->KnownAlbum("Artist2", "Album")); | |
154 | |
155 // GetTrackLocation | |
156 base::FilePath track = | |
157 library_dir().AppendASCII("Track.mp3").NormalizePathSeparators(); | |
158 EXPECT_EQ(track.value(), | |
159 data_provider()->GetTrackLocation( | |
160 "Artist", "Album", | |
161 "Track.mp3").NormalizePathSeparators().value()); | |
162 EXPECT_TRUE(data_provider()->GetTrackLocation("Artist", "Album", | |
163 "Track2.mp3").empty()); | |
164 EXPECT_TRUE(data_provider()->GetTrackLocation("Artist", "Album2", | |
165 "Track.mp3").empty()); | |
166 EXPECT_TRUE(data_provider()->GetTrackLocation("Artist2", "Album", | |
167 "Track.mp3").empty()); | |
168 | |
169 // GetArtistNames | |
170 std::set<ITunesDataProvider::ArtistName> artists = | |
171 data_provider()->GetArtistNames(); | |
172 EXPECT_EQ(1U, artists.size()); | |
173 EXPECT_EQ(std::string("Artist"), *artists.begin()); | |
174 | |
175 // GetAlbumNames | |
176 std::set<ITunesDataProvider::AlbumName> albums = | |
177 data_provider()->GetAlbumNames("Artist"); | |
178 EXPECT_EQ(1U, albums.size()); | |
179 EXPECT_EQ(std::string("Album"), *albums.begin()); | |
180 | |
181 albums = data_provider()->GetAlbumNames("Artist2"); | |
182 EXPECT_EQ(0U, albums.size()); | |
183 | |
184 // GetAlbum | |
185 ITunesDataProvider::Album album = | |
186 data_provider()->GetAlbum("Artist", "Album"); | |
187 EXPECT_EQ(1U, album.size()); | |
188 EXPECT_EQ(track.BaseName().AsUTF8Unsafe(), album.begin()->first); | |
189 EXPECT_EQ(track.value(), | |
190 album.begin()->second.NormalizePathSeparators().value()); | |
191 | |
192 album = data_provider()->GetAlbum("Artist", "Album2"); | |
193 EXPECT_EQ(0U, album.size()); | |
194 | |
195 album = data_provider()->GetAlbum("Artist2", "Album"); | |
196 EXPECT_EQ(0U, album.size()); | |
197 | |
198 TestDone(); | |
199 } | |
200 | |
201 private: | |
202 DISALLOW_COPY_AND_ASSIGN(ITunesDataProviderBasicTest); | |
203 }; | |
204 | |
205 class ITunesDataProviderRefreshTest : public ITunesDataProviderTest { | |
206 public: | |
207 ITunesDataProviderRefreshTest() {} | |
208 virtual ~ITunesDataProviderRefreshTest() {} | |
209 | |
210 void StartTest() { | |
211 base::FilePath track = library_dir().AppendASCII("Track.mp3"); | |
212 std::vector<LibraryEntry> entries; | |
213 entries.push_back(LibraryEntry("Artist", "Album", track)); | |
214 | |
215 WriteLibrary(entries); | |
216 RefreshData(base::Bind(&ITunesDataProviderRefreshTest::CheckData, | |
217 base::Unretained(this))); | |
218 } | |
219 | |
220 void CheckData(bool is_valid) { | |
221 EXPECT_TRUE(is_valid); | |
222 | |
223 // Initial contents. | |
224 ExpectTrackLocation("Artist", "Album", "Track.mp3"); | |
225 ExpectNoTrack("Artist2", "Album2", "Track2.mp3"); | |
226 | |
227 // New file. | |
228 base::FilePath track2 = library_dir().AppendASCII("Track2.mp3"); | |
229 std::vector<LibraryEntry> entries; | |
230 entries.push_back(LibraryEntry("Artist2", "Album2", track2)); | |
231 WriteLibrary(entries); | |
232 | |
233 // Content the same. | |
234 ExpectTrackLocation("Artist", "Album", "Track.mp3"); | |
235 ExpectNoTrack("Artist2", "Album2", "Track2.mp3"); | |
236 | |
237 RefreshData(base::Bind(&ITunesDataProviderRefreshTest::CheckRefresh, | |
238 base::Unretained(this))); | |
239 } | |
240 | |
241 void CheckRefresh(bool is_valid) { | |
242 EXPECT_TRUE(is_valid); | |
243 | |
244 ExpectTrackLocation("Artist2", "Album2", "Track2.mp3"); | |
245 ExpectNoTrack("Artist", "Album", "Track.mp3"); | |
246 | |
247 file_util::WriteFile(XmlFile(), " ", 1); | |
248 | |
249 ExpectTrackLocation("Artist2", "Album2", "Track2.mp3"); | |
250 ExpectNoTrack("Artist", "Album", "Track.mp3"); | |
251 | |
252 RefreshData(base::Bind(&ITunesDataProviderRefreshTest::CheckInvalid, | |
253 base::Unretained(this))); | |
254 } | |
255 | |
256 void CheckInvalid(bool is_valid) { | |
257 EXPECT_FALSE(is_valid); | |
258 TestDone(); | |
259 } | |
260 | |
261 private: | |
262 void ExpectTrackLocation(const std::string& artist, const std::string& album, | |
263 const std::string& track_name) { | |
264 base::FilePath track = | |
265 library_dir().AppendASCII(track_name).NormalizePathSeparators(); | |
266 EXPECT_EQ(track.value(), | |
267 data_provider()->GetTrackLocation( | |
268 artist, album, track_name).NormalizePathSeparators().value()); | |
Greg Billock
2013/07/02 20:29:57
Add << track_name or something to help debug if th
vandebo (ex-Chrome)
2013/07/02 21:00:31
If the comparison fails, it will print .value() of
| |
269 } | |
270 | |
271 void ExpectNoTrack(const std::string& artist, const std::string& album, | |
272 const std::string& track_name) { | |
273 EXPECT_TRUE(data_provider()->GetTrackLocation(artist, album, | |
274 track_name).empty()); | |
275 } | |
276 | |
277 DISALLOW_COPY_AND_ASSIGN(ITunesDataProviderRefreshTest); | |
278 }; | |
279 | |
280 class ITunesDataProviderUniqueNameTest : public ITunesDataProviderTest { | |
281 public: | |
282 ITunesDataProviderUniqueNameTest() {} | |
283 virtual ~ITunesDataProviderUniqueNameTest() {} | |
284 | |
285 void StartTest() { | |
286 base::FilePath track = library_dir().AppendASCII("Track.mp3"); | |
287 std::vector<LibraryEntry> entries; | |
288 entries.push_back(LibraryEntry("Artist", "Album", track)); | |
289 entries.push_back(LibraryEntry("Artist", "Album", track)); | |
290 entries.push_back(LibraryEntry("Artist", "Album2", track)); | |
291 | |
292 WriteLibrary(entries); | |
293 RefreshData(base::Bind(&ITunesDataProviderUniqueNameTest::CheckData, | |
294 base::Unretained(this))); | |
295 } | |
296 | |
297 void CheckData(bool is_valid) { | |
298 EXPECT_TRUE(is_valid); | |
299 | |
300 base::FilePath track = | |
301 library_dir().AppendASCII("Track.mp3").NormalizePathSeparators(); | |
302 EXPECT_EQ(track.value(), | |
Greg Billock
2013/07/02 20:29:57
Maybe add a comment about how dupe names are built
vandebo (ex-Chrome)
2013/07/02 21:00:31
Done.
| |
303 data_provider()->GetTrackLocation( | |
304 "Artist", "Album", | |
305 "Track (1).mp3").NormalizePathSeparators().value()); | |
306 EXPECT_EQ(track.value(), | |
307 data_provider()->GetTrackLocation( | |
308 "Artist", "Album", | |
309 "Track (2).mp3").NormalizePathSeparators().value()); | |
310 EXPECT_EQ(track.value(), | |
311 data_provider()->GetTrackLocation( | |
312 "Artist", "Album2", | |
313 "Track.mp3").NormalizePathSeparators().value()); | |
314 | |
315 TestDone(); | |
316 } | |
317 | |
318 private: | |
319 DISALLOW_COPY_AND_ASSIGN(ITunesDataProviderUniqueNameTest); | |
320 }; | |
321 | |
322 IN_PROC_BROWSER_TEST_F(ITunesDataProviderBasicTest, BasicTest) { | |
323 RunTestOnMediaTaskRunner(); | |
324 } | |
325 | |
326 IN_PROC_BROWSER_TEST_F(ITunesDataProviderRefreshTest, RefreshTest) { | |
327 RunTestOnMediaTaskRunner(); | |
328 } | |
329 | |
330 IN_PROC_BROWSER_TEST_F(ITunesDataProviderUniqueNameTest, UniqueNameTest) { | |
331 RunTestOnMediaTaskRunner(); | |
332 } | |
333 | |
334 } // namespace itunes | |
OLD | NEW |