This source file includes following definitions.
- callback_
- OnLibraryChanged
- SetUp
- RunTest
- WriteLibrary
- SetLibraryChangeCallback
- data_provider
- library_dir
- XmlFile
- ExpectTrackLocation
- ExpectNoTrack
- SetUpLibrary
- TestDone
- StartTestOnMediaTaskRunner
- OnLibraryChanged
- WriteLibraryInternal
- SetUpLibrary
- StartTest
- SetUpLibrary
- StartTest
- CheckAfterWrite
- CheckRefresh
- SetUpLibrary
- StartTest
- CheckInvalid
- SetUpLibrary
- StartTest
- SetUpLibrary
- StartTest
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
#include <string>
#include <vector>
#include "base/bind.h"
#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
#include "base/format_macros.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "chrome/browser/media_galleries/fileapi/itunes_data_provider.h"
#include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h"
#include "chrome/browser/media_galleries/imported_media_gallery_registry.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "content/public/browser/browser_thread.h"
#include "url/gurl.h"
namespace itunes {
namespace {
struct LibraryEntry {
LibraryEntry(const std::string& artist, const std::string& album,
const base::FilePath& location)
: artist(artist),
album(album),
location(location) {
}
std::string artist;
std::string album;
base::FilePath location;
};
const char kDeNormalizedName[] = {
'c', static_cast<unsigned char>(0xCC), static_cast<unsigned char>(0xA7), 0};
const char kNormalizedName[] = {
static_cast<unsigned char>(0xC3), static_cast<unsigned char>(0xA7), 0};
}
class TestITunesDataProvider : public ITunesDataProvider {
public:
TestITunesDataProvider(const base::FilePath& xml_library_path,
const base::Closure& callback)
: ITunesDataProvider(xml_library_path),
callback_(callback) {
}
virtual ~TestITunesDataProvider() {}
private:
virtual void OnLibraryChanged(const base::FilePath& path,
bool error) OVERRIDE {
ITunesDataProvider::OnLibraryChanged(path, error);
callback_.Run();
}
base::Closure callback_;
DISALLOW_COPY_AND_ASSIGN(TestITunesDataProvider);
};
class ITunesDataProviderTest : public InProcessBrowserTest {
public:
ITunesDataProviderTest() {}
virtual ~ITunesDataProviderTest() {}
protected:
virtual void SetUp() OVERRIDE {
ASSERT_TRUE(library_dir_.CreateUniqueTempDir());
WriteLibraryInternal(SetUpLibrary());
ImportedMediaGalleryRegistry::GetInstance();
InProcessBrowserTest::SetUp();
}
void RunTest() {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
base::RunLoop loop;
quit_closure_ = loop.QuitClosure();
MediaFileSystemBackend::MediaTaskRunner()->PostTask(
FROM_HERE,
base::Bind(&ITunesDataProviderTest::StartTestOnMediaTaskRunner,
base::Unretained(this)));
loop.Run();
}
void WriteLibrary(const std::vector<LibraryEntry>& entries,
const base::Closure& callback) {
SetLibraryChangeCallback(callback);
WriteLibraryInternal(entries);
}
void SetLibraryChangeCallback(const base::Closure& callback) {
EXPECT_TRUE(library_changed_callback_.is_null());
library_changed_callback_ = callback;
}
ITunesDataProvider* data_provider() const {
return ImportedMediaGalleryRegistry::ITunesDataProvider();
}
const base::FilePath& library_dir() const {
return library_dir_.path();
}
base::FilePath XmlFile() const {
return library_dir_.path().AppendASCII("library.xml");
}
void ExpectTrackLocation(const std::string& artist, const std::string& album,
const std::string& track_name) {
base::FilePath track =
library_dir().AppendASCII(track_name).NormalizePathSeparators();
EXPECT_EQ(track.value(),
data_provider()->GetTrackLocation(
artist, album, track_name).NormalizePathSeparators().value());
}
void ExpectNoTrack(const std::string& artist, const std::string& album,
const std::string& track_name) {
EXPECT_TRUE(data_provider()->GetTrackLocation(
artist, album, track_name).empty()) << track_name;
}
virtual std::vector<LibraryEntry> SetUpLibrary() {
return std::vector<LibraryEntry>();
}
virtual void StartTest(bool parse_success) = 0;
void TestDone() {
DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
ImportedMediaGalleryRegistry* imported_registry =
ImportedMediaGalleryRegistry::GetInstance();
imported_registry->itunes_data_provider_.reset();
content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
quit_closure_);
}
private:
void StartTestOnMediaTaskRunner() {
DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
ImportedMediaGalleryRegistry* imported_registry =
ImportedMediaGalleryRegistry::GetInstance();
imported_registry->itunes_data_provider_.reset(
new TestITunesDataProvider(
XmlFile(),
base::Bind(&ITunesDataProviderTest::OnLibraryChanged,
base::Unretained(this))));
data_provider()->RefreshData(base::Bind(&ITunesDataProviderTest::StartTest,
base::Unretained(this)));
};
void OnLibraryChanged() {
DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread());
if (!library_changed_callback_.is_null()) {
library_changed_callback_.Run();
library_changed_callback_.Reset();
}
}
void WriteLibraryInternal(const std::vector<LibraryEntry>& entries) {
if (!entries.size())
return;
std::string xml = "<plist><dict><key>Tracks</key><dict>\n";
for (size_t i = 0; i < entries.size(); ++i) {
std::string separator;
#if defined(OS_WIN)
separator = "/";
#endif
GURL location("file://localhost" + separator +
entries[i].location.AsUTF8Unsafe());
std::string entry_string = base::StringPrintf(
"<key>%" PRIuS "</key><dict>\n"
" <key>Track ID</key><integer>%" PRIuS "</integer>\n"
" <key>Location</key><string>%s</string>\n"
" <key>Artist</key><string>%s</string>\n"
" <key>Album</key><string>%s</string>\n"
"</dict>\n",
i + 1, i + 1, location.spec().c_str(), entries[i].artist.c_str(),
entries[i].album.c_str());
xml += entry_string;
}
xml += "</dict></dict></plist>\n";
ASSERT_EQ(static_cast<int>(xml.size()),
base::WriteFile(XmlFile(), xml.c_str(), xml.size()));
}
base::ScopedTempDir library_dir_;
base::Closure library_changed_callback_;
base::Closure quit_closure_;
DISALLOW_COPY_AND_ASSIGN(ITunesDataProviderTest);
};
class ITunesDataProviderBasicTest : public ITunesDataProviderTest {
public:
ITunesDataProviderBasicTest() {}
virtual ~ITunesDataProviderBasicTest() {}
virtual std::vector<LibraryEntry> SetUpLibrary() OVERRIDE {
base::FilePath track = library_dir().AppendASCII("Track.mp3");
std::vector<LibraryEntry> entries;
entries.push_back(LibraryEntry("Artist", "Album", track));
return entries;
}
virtual void StartTest(bool parse_success) OVERRIDE {
EXPECT_TRUE(parse_success);
EXPECT_TRUE(data_provider()->KnownArtist("Artist"));
EXPECT_FALSE(data_provider()->KnownArtist("Artist2"));
EXPECT_TRUE(data_provider()->KnownAlbum("Artist", "Album"));
EXPECT_FALSE(data_provider()->KnownAlbum("Artist", "Album2"));
EXPECT_FALSE(data_provider()->KnownAlbum("Artist2", "Album"));
ExpectTrackLocation("Artist", "Album", "Track.mp3");
ExpectNoTrack("Artist", "Album", "Track2.mp3");
ExpectNoTrack("Artist", "Album2", "Track.mp3");
ExpectNoTrack("Artist2", "Album", "Track.mp3");
std::set<ITunesDataProvider::ArtistName> artists =
data_provider()->GetArtistNames();
ASSERT_EQ(1U, artists.size());
EXPECT_EQ("Artist", *artists.begin());
std::set<ITunesDataProvider::AlbumName> albums =
data_provider()->GetAlbumNames("Artist");
ASSERT_EQ(1U, albums.size());
EXPECT_EQ("Album", *albums.begin());
albums = data_provider()->GetAlbumNames("Artist2");
EXPECT_EQ(0U, albums.size());
base::FilePath track =
library_dir().AppendASCII("Track.mp3").NormalizePathSeparators();
ITunesDataProvider::Album album =
data_provider()->GetAlbum("Artist", "Album");
ASSERT_EQ(1U, album.size());
EXPECT_EQ(track.BaseName().AsUTF8Unsafe(), album.begin()->first);
EXPECT_EQ(track.value(),
album.begin()->second.NormalizePathSeparators().value());
album = data_provider()->GetAlbum("Artist", "Album2");
EXPECT_EQ(0U, album.size());
album = data_provider()->GetAlbum("Artist2", "Album");
EXPECT_EQ(0U, album.size());
TestDone();
}
private:
DISALLOW_COPY_AND_ASSIGN(ITunesDataProviderBasicTest);
};
class ITunesDataProviderRefreshTest : public ITunesDataProviderTest {
public:
ITunesDataProviderRefreshTest() {}
virtual ~ITunesDataProviderRefreshTest() {}
virtual std::vector<LibraryEntry> SetUpLibrary() OVERRIDE {
base::FilePath track = library_dir().AppendASCII("Track.mp3");
std::vector<LibraryEntry> entries;
entries.push_back(LibraryEntry("Artist", "Album", track));
return entries;
}
virtual void StartTest(bool parse_success) OVERRIDE {
EXPECT_TRUE(parse_success);
ExpectTrackLocation("Artist", "Album", "Track.mp3");
ExpectNoTrack("Artist2", "Album2", "Track2.mp3");
base::FilePath track2 = library_dir().AppendASCII("Track2.mp3");
std::vector<LibraryEntry> entries;
entries.push_back(LibraryEntry("Artist2", "Album2", track2));
WriteLibrary(entries,
base::Bind(&ITunesDataProviderRefreshTest::CheckAfterWrite,
base::Unretained(this)));
}
void CheckAfterWrite() {
ExpectTrackLocation("Artist", "Album", "Track.mp3");
ExpectNoTrack("Artist2", "Album2", "Track2.mp3");
data_provider()->RefreshData(
base::Bind(&ITunesDataProviderRefreshTest::CheckRefresh,
base::Unretained(this)));
}
void CheckRefresh(bool is_valid) {
EXPECT_TRUE(is_valid);
ExpectTrackLocation("Artist2", "Album2", "Track2.mp3");
ExpectNoTrack("Artist", "Album", "Track.mp3");
TestDone();
}
private:
DISALLOW_COPY_AND_ASSIGN(ITunesDataProviderRefreshTest);
};
class ITunesDataProviderInvalidTest : public ITunesDataProviderTest {
public:
ITunesDataProviderInvalidTest() {}
virtual ~ITunesDataProviderInvalidTest() {}
virtual std::vector<LibraryEntry> SetUpLibrary() OVERRIDE {
base::FilePath track = library_dir().AppendASCII("Track.mp3");
std::vector<LibraryEntry> entries;
entries.push_back(LibraryEntry("Artist", "Album", track));
return entries;
}
virtual void StartTest(bool parse_success) OVERRIDE {
EXPECT_TRUE(parse_success);
SetLibraryChangeCallback(
base::Bind(&ITunesDataProvider::RefreshData,
base::Unretained(data_provider()),
base::Bind(&ITunesDataProviderInvalidTest::CheckInvalid,
base::Unretained(this))));
ASSERT_EQ(1L, base::WriteFile(XmlFile(), " ", 1));
}
void CheckInvalid(bool is_valid) {
EXPECT_FALSE(is_valid);
TestDone();
}
private:
DISALLOW_COPY_AND_ASSIGN(ITunesDataProviderInvalidTest);
};
class ITunesDataProviderUniqueNameTest : public ITunesDataProviderTest {
public:
ITunesDataProviderUniqueNameTest() {}
virtual ~ITunesDataProviderUniqueNameTest() {}
virtual std::vector<LibraryEntry> SetUpLibrary() OVERRIDE {
base::FilePath track = library_dir().AppendASCII("Track.mp3");
std::vector<LibraryEntry> entries;
entries.push_back(LibraryEntry("Artist", "Album", track));
entries.push_back(LibraryEntry("Artist", "Album", track));
entries.push_back(LibraryEntry("Artist", "Album2", track));
return entries;
}
virtual void StartTest(bool parse_success) OVERRIDE {
EXPECT_TRUE(parse_success);
base::FilePath track =
library_dir().AppendASCII("Track.mp3").NormalizePathSeparators();
EXPECT_EQ(track.value(),
data_provider()->GetTrackLocation(
"Artist", "Album",
"Track (1).mp3").NormalizePathSeparators().value());
EXPECT_EQ(track.value(),
data_provider()->GetTrackLocation(
"Artist", "Album",
"Track (2).mp3").NormalizePathSeparators().value());
EXPECT_EQ(track.value(),
data_provider()->GetTrackLocation(
"Artist", "Album2",
"Track.mp3").NormalizePathSeparators().value());
TestDone();
}
private:
DISALLOW_COPY_AND_ASSIGN(ITunesDataProviderUniqueNameTest);
};
class ITunesDataProviderEscapeTest : public ITunesDataProviderTest {
public:
ITunesDataProviderEscapeTest() {}
virtual ~ITunesDataProviderEscapeTest() {}
virtual std::vector<LibraryEntry> SetUpLibrary() OVERRIDE {
base::FilePath track = library_dir().AppendASCII("Track:1.mp3");
std::vector<LibraryEntry> entries;
entries.push_back(LibraryEntry("Artist:/name", "Album:name/", track));
entries.push_back(LibraryEntry("Artist/name", "Album:name", track));
entries.push_back(LibraryEntry("Artist/name", "Album:name", track));
entries.push_back(LibraryEntry(kDeNormalizedName, kNormalizedName, track));
return entries;
}
virtual void StartTest(bool parse_success) OVERRIDE {
EXPECT_TRUE(parse_success);
base::FilePath track =
library_dir().AppendASCII("Track:1.mp3").NormalizePathSeparators();
EXPECT_EQ(track.value(),
data_provider()->GetTrackLocation(
"Artist__name", "Album_name_",
"Track_1.mp3").NormalizePathSeparators().value());
EXPECT_EQ(track.value(),
data_provider()->GetTrackLocation(
"Artist_name", "Album_name",
"Track_1 (2).mp3").NormalizePathSeparators().value());
EXPECT_EQ(track.value(),
data_provider()->GetTrackLocation(
"Artist_name", "Album_name",
"Track_1 (3).mp3").NormalizePathSeparators().value());
EXPECT_EQ(track.value(),
data_provider()->GetTrackLocation(
kNormalizedName, kNormalizedName,
"Track_1.mp3").NormalizePathSeparators().value());
TestDone();
}
private:
DISALLOW_COPY_AND_ASSIGN(ITunesDataProviderEscapeTest);
};
IN_PROC_BROWSER_TEST_F(ITunesDataProviderBasicTest, BasicTest) {
RunTest();
}
IN_PROC_BROWSER_TEST_F(ITunesDataProviderRefreshTest, RefreshTest) {
RunTest();
}
IN_PROC_BROWSER_TEST_F(ITunesDataProviderInvalidTest, InvalidTest) {
RunTest();
}
IN_PROC_BROWSER_TEST_F(ITunesDataProviderUniqueNameTest, UniqueNameTest) {
RunTest();
}
IN_PROC_BROWSER_TEST_F(ITunesDataProviderEscapeTest, EscapeTest) {
RunTest();
}
}