Commit 7bcae5cc authored by Hugo Beauzée-Luyssen's avatar Hugo Beauzée-Luyssen

Albums/Artist: Use Media instead of AlbumTrack

parent c7a9e9bc
......@@ -37,7 +37,6 @@ class IAlbumTrack
virtual const std::string& title() = 0;
virtual unsigned int trackNumber() = 0;
virtual std::shared_ptr<IAlbum> album() = 0;
virtual std::vector<ArtistPtr> artists() const = 0;
virtual std::vector<MediaPtr> files() = 0;
};
......
......@@ -35,5 +35,5 @@ public:
virtual const std::string& name() const = 0;
virtual const std::string& shortBio() const = 0;
virtual std::vector<AlbumPtr> albums() const = 0;
virtual std::vector<AlbumTrackPtr> tracks() const = 0;
virtual std::vector<AlbumTrackPtr> media() const = 0;
};
......@@ -57,6 +57,7 @@ class IMedia
virtual bool addLabel( LabelPtr label ) = 0;
virtual bool removeLabel( LabelPtr label ) = 0;
virtual MoviePtr movie() = 0;
virtual std::vector<ArtistPtr> artists() const = 0;
virtual std::vector<std::shared_ptr<ILabel> > labels() = 0;
virtual std::vector<VideoTrackPtr> videoTracks() = 0;
virtual std::vector<AudioTrackPtr> audioTracks() = 0;
......
......@@ -23,6 +23,7 @@
#include "Album.h"
#include "AlbumTrack.h"
#include "Artist.h"
#include "Media.h"
#include "database/SqliteTools.h"
......@@ -109,16 +110,16 @@ time_t Album::lastSyncDate() const
return m_lastSyncDate;
}
std::vector<std::shared_ptr<IAlbumTrack>> Album::tracks() const
std::vector<AlbumTrackPtr> Album::tracks() const
{
static const std::string req = "SELECT * FROM " + policy::AlbumTrackTable::Name
+ " WHERE album_id = ?";
return AlbumTrack::fetchAll( m_dbConnection, req, m_id );
}
std::shared_ptr<AlbumTrack> Album::addTrack( const std::string& title, unsigned int trackNb )
std::shared_ptr<AlbumTrack> Album::addTrack(std::shared_ptr<Media> media, unsigned int trackNb )
{
return AlbumTrack::create( m_dbConnection, m_id, title, trackNb );
return AlbumTrack::create( m_dbConnection, m_id, media->name(), trackNb );
}
std::vector<ArtistPtr> Album::artists() const
......
......@@ -34,6 +34,7 @@
class Album;
class AlbumTrack;
class Artist;
class Media;
namespace policy
{
......@@ -62,8 +63,8 @@ class Album : public IAlbum, public Cache<Album, IAlbum, policy::AlbumTable>
virtual const std::string& artworkUrl() const override;
bool setArtworkUrl( const std::string& artworkUrl );
virtual time_t lastSyncDate() const override;
virtual std::vector<std::shared_ptr<IAlbumTrack> > tracks() const override;
std::shared_ptr<AlbumTrack> addTrack( const std::string& title, unsigned int trackNb );
virtual std::vector<AlbumTrackPtr> tracks() const override;
std::shared_ptr<AlbumTrack> addTrack( std::shared_ptr<Media> media, unsigned int trackNb );
virtual std::vector<ArtistPtr> artists() const override;
bool addArtist( std::shared_ptr<Artist> artist );
......
......@@ -22,7 +22,6 @@
#include "AlbumTrack.h"
#include "Album.h"
#include "Artist.h"
#include "Media.h"
#include "database/SqliteTools.h"
#include "logging/Logger.h"
......@@ -66,17 +65,7 @@ bool AlbumTrack::createTable( DBConnection dbConnection )
"album_id UNSIGNED INTEGER NOT NULL,"
"FOREIGN KEY (album_id) REFERENCES Album(id_album) ON DELETE CASCADE"
")";
static const std::string reqRel = "CREATE TABLE IF NOT EXISTS TrackArtistRelation("
"id_track INTEGER NOT NULL,"
"id_artist INTEGER,"
"PRIMARY KEY (id_track, id_artist),"
"FOREIGN KEY(id_track) REFERENCES " + policy::AlbumTrackTable::Name + "("
+ policy::AlbumTrackTable::CacheColumn + ") ON DELETE CASCADE,"
"FOREIGN KEY(id_artist) REFERENCES " + policy::ArtistTable::Name + "("
+ policy::ArtistTable::CacheColumn + ") ON DELETE CASCADE"
")";
return sqlite::Tools::executeRequest( dbConnection, req ) &&
sqlite::Tools::executeRequest( dbConnection, reqRel );
return sqlite::Tools::executeRequest( dbConnection, req );
}
std::shared_ptr<AlbumTrack> AlbumTrack::create(DBConnection dbConnection, unsigned int albumId, const std::string& name, unsigned int trackNb)
......@@ -139,22 +128,6 @@ bool AlbumTrack::destroy()
return _Cache::destroy( m_dbConnection, this );
}
bool AlbumTrack::addArtist( ArtistPtr artist )
{
static const std::string req = "INSERT INTO TrackArtistRelation VALUES(?, ?)";
// If track's ID is 0, the request will fail due to table constraints
sqlite::ForeignKey artistForeignKey( artist != nullptr ? artist->id() : 0 );
return sqlite::Tools::executeRequest( m_dbConnection, req, m_id, artistForeignKey );
}
std::vector<ArtistPtr> AlbumTrack::artists() const
{
static const std::string req = "SELECT art.* FROM " + policy::ArtistTable::Name + " art "
"LEFT JOIN TrackArtistRelation tar ON tar.id_artist = art.id_artist "
"WHERE tar.id_track = ?";
return Artist::fetchAll( m_dbConnection, req, m_id );
}
std::vector<MediaPtr> AlbumTrack::files()
{
static const std::string req = "SELECT * FROM " + policy::MediaTable::Name
......
......@@ -57,11 +57,9 @@ class AlbumTrack : public IAlbumTrack, public Cache<AlbumTrack, IAlbumTrack, pol
virtual const std::string& title() override;
virtual unsigned int trackNumber() override;
virtual std::shared_ptr<IAlbum> album() override;
bool destroy();
bool addArtist( ArtistPtr artist );
virtual std::vector<ArtistPtr> artists() const override;
virtual std::vector<MediaPtr> files() override;
bool destroy();
static bool createTable( DBConnection dbConnection );
static std::shared_ptr<AlbumTrack> create( DBConnection dbConnection, unsigned int albumId,
const std::string& name, unsigned int trackNb );
......
......@@ -23,6 +23,7 @@
#include "Artist.h"
#include "Album.h"
#include "AlbumTrack.h"
#include "Media.h"
#include "database/SqliteTools.h"
......@@ -86,22 +87,22 @@ std::vector<AlbumPtr> Artist::albums() const
return Album::fetchAll( m_dbConnection, req, m_id );
}
std::vector<AlbumTrackPtr> Artist::tracks() const
std::vector<AlbumTrackPtr> Artist::media() const
{
if ( m_id )
{
static const std::string req = "SELECT tra.* FROM " + policy::AlbumTrackTable::Name + " tra "
"LEFT JOIN TrackArtistRelation tar ON tar.id_track = tra.id_track "
"WHERE tar.id_artist = ?";
static const std::string req = "SELECT mar.* FROM " + policy::MediaTable::Name + " med "
"LEFT JOIN MediaArtistRelation mar ON mar.id_media = med.id_media "
"WHERE mar.id_artist = ?";
return AlbumTrack::fetchAll( m_dbConnection, req, m_id );
}
else
{
// Not being able to rely on ForeignKey here makes me a saaaaad panda...
// But sqlite only accepts "IS NULL" to compare against NULL...
static const std::string req = "SELECT tra.* FROM " + policy::AlbumTrackTable::Name + " tra "
"LEFT JOIN TrackArtistRelation tar ON tar.id_track = tra.id_track "
"WHERE tar.id_artist IS NULL";
static const std::string req = "SELECT mar.* FROM " + policy::MediaTable::Name + " med "
"LEFT JOIN MediaArtistRelation mar ON mar.id_media = med.id_media "
"WHERE mar.id_artist IS NULL";
return AlbumTrack::fetchAll( m_dbConnection, req, m_id );
}
}
......@@ -115,7 +116,17 @@ bool Artist::createTable( DBConnection dbConnection )
"name TEXT UNIQUE ON CONFLICT FAIL,"
"shortbio TEXT"
")";
return sqlite::Tools::executeRequest( dbConnection, req );
static const std::string reqRel = "CREATE TABLE IF NOT EXISTS MediaArtistRelation("
"id_media INTEGER NOT NULL,"
"id_artist INTEGER,"
"PRIMARY KEY (id_media, id_artist),"
"FOREIGN KEY(id_media) REFERENCES " + policy::MediaTable::Name +
"(id_media) ON DELETE CASCADE,"
"FOREIGN KEY(id_artist) REFERENCES " + policy::ArtistTable::Name + "("
+ policy::ArtistTable::CacheColumn + ") ON DELETE CASCADE"
")";
return sqlite::Tools::executeRequest( dbConnection, req ) &&
sqlite::Tools::executeRequest( dbConnection, reqRel );
}
std::shared_ptr<Artist> Artist::create( DBConnection dbConnection, const std::string &name )
......
......@@ -57,7 +57,7 @@ public:
virtual const std::string& shortBio() const override;
bool setShortBio( const std::string& shortBio );
virtual std::vector<AlbumPtr> albums() const override;
virtual std::vector<AlbumTrackPtr> tracks() const override;
virtual std::vector<AlbumTrackPtr> media() const override;
static bool createTable( DBConnection dbConnection );
static std::shared_ptr<Artist> create( DBConnection dbConnection, const std::string& name );
......
......@@ -58,7 +58,7 @@ const std::string& Label::name()
std::vector<MediaPtr> Label::files()
{
static const std::string req = "SELECT f.* FROM " + policy::MediaTable::Name + " f "
"LEFT JOIN LabelFileRelation lfr ON lfr.id_file = f.id_file "
"LEFT JOIN LabelFileRelation lfr ON lfr.id_media = f.id_media "
"WHERE lfr.id_label = ?";
return Media::fetchAll( m_dbConnection, req, m_id );
}
......@@ -83,10 +83,10 @@ bool Label::createTable(DBConnection dbConnection)
return false;
req = "CREATE TABLE IF NOT EXISTS LabelFileRelation("
"id_label INTEGER,"
"id_file INTEGER,"
"PRIMARY KEY (id_label, id_file),"
"id_media INTEGER,"
"PRIMARY KEY (id_label, id_media),"
"FOREIGN KEY(id_label) REFERENCES Label(id_label) ON DELETE CASCADE,"
"FOREIGN KEY(id_file) REFERENCES File(id_file) ON DELETE CASCADE);";
"FOREIGN KEY(id_media) REFERENCES Media(id_media) ON DELETE CASCADE);";
return sqlite::Tools::executeRequest( dbConnection, req );
}
......
......@@ -27,6 +27,7 @@
#include "Album.h"
#include "AlbumTrack.h"
#include "Artist.h"
#include "AudioTrack.h"
#include "Media.h"
#include "Folder.h"
......@@ -110,6 +111,22 @@ bool Media::setAlbumTrack( AlbumTrackPtr albumTrack )
return true;
}
bool Media::addArtist( ArtistPtr artist )
{
static const std::string req = "INSERT INTO MediaArtistRelation VALUES(?, ?)";
// If track's ID is 0, the request will fail due to table constraints
sqlite::ForeignKey artistForeignKey( artist != nullptr ? artist->id() : 0 );
return sqlite::Tools::executeRequest( m_dbConnection, req, m_id, artistForeignKey );
}
std::vector<ArtistPtr> Media::artists() const
{
static const std::string req = "SELECT art.* FROM " + policy::ArtistTable::Name + " art "
"LEFT JOIN MediaArtistRelation mar ON mar.id_artist = art.id_artist "
"WHERE mar.id_media = ?";
return Artist::fetchAll( m_dbConnection, req, m_id );
}
int64_t Media::duration() const
{
return m_duration;
......
......@@ -74,6 +74,8 @@ class Media : public IMedia, public Cache<Media, IMedia, policy::MediaTable, pol
bool setName( const std::string& name );
virtual AlbumTrackPtr albumTrack() override;
bool setAlbumTrack( AlbumTrackPtr albumTrack );
bool addArtist( ArtistPtr artist );
virtual std::vector<ArtistPtr> artists() const override;
virtual int64_t duration() const override;
bool setDuration( int64_t duration);
virtual std::shared_ptr<IShowEpisode> showEpisode() override;
......
......@@ -314,7 +314,7 @@ ArtistPtr MediaLibrary::unknownArtist()
{
if ( m_unknownArtist != nullptr )
return m_unknownArtist;
static const std::string req = "SELECT id_track FROM TrackArtistRelation "
static const std::string req = "SELECT id_media FROM MediaArtistRelation "
"WHERE id_artist IS NULL LIMIT 1";
if ( sqlite::Tools::hasResults( m_dbConnection.get(), req ) == true )
{
......
......@@ -139,12 +139,12 @@ bool VLCMetadataService::parseAudioFile( std::shared_ptr<Media> file, VLC::Media
std::shared_ptr<AlbumTrack> track;
if ( album != nullptr )
{
track = handleTrack( album, media );
track = handleTrack( album, file, media );
if ( track != nullptr )
file->setAlbumTrack( track );
}
return handleArtist( album, track, media, newAlbum );
return handleArtist( album, file, media, newAlbum );
}
bool VLCMetadataService::parseVideoFile( std::shared_ptr<Media> file, VLC::Media& media ) const
......@@ -185,14 +185,12 @@ bool VLCMetadataService::parseVideoFile( std::shared_ptr<Media> file, VLC::Media
return true;
}
bool VLCMetadataService::handleArtist( std::shared_ptr<Album> album, std::shared_ptr<AlbumTrack> track, VLC::Media& media, bool newAlbum ) const
bool VLCMetadataService::handleArtist( std::shared_ptr<Album> album, std::shared_ptr<Media> media, VLC::Media& vlcMedia, bool newAlbum ) const
{
// For now we don't handle artist if the file isn't an AlbumTrack.
// Let's not crash first, then fix it properly
if (track == nullptr)
return true;
assert(media != nullptr);
auto newArtist = false;
auto artistName = media.meta( libvlc_meta_Artist );
auto artistName = vlcMedia.meta( libvlc_meta_Artist );
if ( artistName.length() != 0 )
{
auto artist = std::static_pointer_cast<Artist>( m_ml->artist( artistName ) );
......@@ -207,7 +205,7 @@ bool VLCMetadataService::handleArtist( std::shared_ptr<Album> album, std::shared
}
newArtist = true;
}
track->addArtist( artist );
media->addArtist( artist );
// If this is either a new album or a new artist, we need to add the relationship between the two.
if ( album != nullptr && ( newAlbum == true || newArtist == true ) )
{
......@@ -216,23 +214,23 @@ bool VLCMetadataService::handleArtist( std::shared_ptr<Album> album, std::shared
}
}
else
track->addArtist( nullptr );
media->addArtist( nullptr );
return true;
}
std::shared_ptr<AlbumTrack> VLCMetadataService::handleTrack(std::shared_ptr<Album> album, VLC::Media& media) const
std::shared_ptr<AlbumTrack> VLCMetadataService::handleTrack(std::shared_ptr<Album> album, std::shared_ptr<Media> media, VLC::Media& vlcMedia) const
{
auto trackNbStr = media.meta( libvlc_meta_TrackNumber );
auto trackNbStr = vlcMedia.meta( libvlc_meta_TrackNumber );
if ( trackNbStr.length() == 0 )
{
LOG_WARN( "Failed to get track id" );
return nullptr;
}
auto artwork = media.meta( libvlc_meta_ArtworkURL );
auto artwork = vlcMedia.meta( libvlc_meta_ArtworkURL );
if ( artwork.length() != 0 )
album->setArtworkUrl( artwork );
auto title = media.meta( libvlc_meta_Title );
auto title = vlcMedia.meta( libvlc_meta_Title );
if ( title.length() == 0 )
{
LOG_WARN( "Failed to get track title" );
......@@ -240,13 +238,13 @@ std::shared_ptr<AlbumTrack> VLCMetadataService::handleTrack(std::shared_ptr<Albu
title += trackNbStr;
}
unsigned int trackNb = std::stoi( trackNbStr );
auto track = std::static_pointer_cast<AlbumTrack>( album->addTrack( title, trackNb ) );
auto track = std::static_pointer_cast<AlbumTrack>( album->addTrack( media, trackNb ) );
if ( track == nullptr )
{
LOG_ERROR( "Failed to create album track" );
return nullptr;
}
auto genre = media.meta( libvlc_meta_Genre );
auto genre = vlcMedia.meta( libvlc_meta_Genre );
if ( genre.length() != 0 )
{
track->setGenre( genre );
......
......@@ -54,8 +54,8 @@ class VLCMetadataService : public IMetadataService
ServiceStatus handleMediaMeta(std::shared_ptr<Media> file , VLC::Media &media) const;
bool parseAudioFile(std::shared_ptr<Media> file, VLC::Media &media) const;
bool parseVideoFile(std::shared_ptr<Media> file, VLC::Media &media) const;
bool handleArtist(std::shared_ptr<Album> album, std::shared_ptr<AlbumTrack> track, VLC::Media& media, bool newAlbum ) const;
std::shared_ptr<AlbumTrack> handleTrack(std::shared_ptr<Album> album, VLC::Media& media ) const;
bool handleArtist(std::shared_ptr<Album> album, std::shared_ptr<Media> media, VLC::Media& vlcMedia, bool newAlbum ) const;
std::shared_ptr<AlbumTrack> handleTrack(std::shared_ptr<Album> album, std::shared_ptr<Media> media , VLC::Media& vlcMedia) const;
VLC::Instance m_instance;
IMetadataServiceCb* m_cb;
......
......@@ -30,50 +30,4 @@ class AlbumTracks : public Tests
{
};
TEST_F( AlbumTracks, Artists )
{
auto album = ml->createAlbum( "album" );
auto artist1 = ml->createArtist( "artist 1" );
auto artist2 = ml->createArtist( "artist 2" );
album->addTrack( "track 1", 1 );
album->addTrack( "track 2", 2 );
album->addTrack( "track 3", 3 );
ASSERT_NE( artist1, nullptr );
ASSERT_NE( artist2, nullptr );
auto tracks = album->tracks();
for ( auto& it : tracks )
{
auto t = std::static_pointer_cast<AlbumTrack>( it );
t->addArtist( artist1 );
t->addArtist( artist2 );
auto artists = t->artists();
ASSERT_EQ( artists.size(), 2u );
}
auto artists = ml->artists();
for ( auto& a : artists )
{
auto tracks = a->tracks();
ASSERT_EQ( tracks.size(), 3u );
}
Reload();
auto album2 = ml->album( "album" );
auto tracks2 = album2->tracks();
for ( auto& t : tracks2 )
{
auto artists = t->artists();
ASSERT_EQ( artists.size(), 2u );
}
auto artists2 = ml->artists();
for ( auto& a : artists2 )
{
auto tracks = a->tracks();
ASSERT_EQ( tracks.size(), 3u );
}
}
......@@ -58,7 +58,8 @@ TEST_F( Albums, Fetch )
TEST_F( Albums, AddTrack )
{
auto a = ml->createAlbum( "albumtag" );
auto track = a->addTrack( "track", 10 );
auto f = ml->addFile( "track.mp3", nullptr );
auto track = a->addTrack( f, 10 );
ASSERT_NE( track, nullptr );
auto tracks = a->tracks();
......@@ -75,9 +76,9 @@ TEST_F( Albums, AddTrack )
TEST_F( Albums, AssignTrack )
{
auto f = ml->addFile( "file.avi", nullptr );
auto f = ml->addFile( "file.mp3", nullptr );
auto a = ml->createAlbum( "album" );
auto t = a->addTrack( "track", 1 );
auto t = a->addTrack( f, 1 );
ASSERT_EQ( f->albumTrack(), nullptr );
bool res = f->setAlbumTrack( t );
......@@ -87,30 +88,31 @@ TEST_F( Albums, AssignTrack )
Reload();
f = std::static_pointer_cast<Media>( ml->file( "file.avi" ) );
f = std::static_pointer_cast<Media>( ml->file( "file.mp3" ) );
t = std::static_pointer_cast<AlbumTrack>( f->albumTrack() );
ASSERT_NE( t, nullptr );
ASSERT_EQ( t->title(), "track" );
ASSERT_EQ( t->title(), f->name() );
}
TEST_F( Albums, DeleteTrack )
{
auto f = ml->addFile( "file.avi", nullptr );
auto f = ml->addFile( "file.mp3", nullptr );
auto a = ml->createAlbum( "album" );
auto t = a->addTrack( "track", 1 );
auto t = a->addTrack( f, 1 );
f->setAlbumTrack( t );
bool res = t->destroy();
ASSERT_TRUE( res );
auto f2 = ml->file( "file.avi" );
auto f2 = ml->file( "file.mp3" );
ASSERT_EQ( f2, nullptr );
}
TEST_F( Albums, SetGenre )
{
auto a = ml->createAlbum( "album" );
auto t = a->addTrack( "track", 1 );
auto f = ml->addFile( "track.mp3", nullptr );
auto t = a->addTrack( f, 1 );
t->setGenre( "happy underground post progressive death metal" );
ASSERT_EQ( t->genre(), "happy underground post progressive death metal" );
......@@ -166,13 +168,13 @@ TEST_F( Albums, FetchAlbumFromTrack )
{
{
auto a = ml->createAlbum( "album" );
auto f = ml->addFile( "file.avi", nullptr );
auto t = a->addTrack( "track 1", 1 );
auto f = ml->addFile( "file.mp3", nullptr );
auto t = a->addTrack( f, 1 );
f->setAlbumTrack( t );
}
Reload();
auto f = ml->file( "file.avi" );
auto f = ml->file( "file.mp3" );
auto t = f->albumTrack();
auto a = t->album();
ASSERT_NE( a, nullptr );
......@@ -182,14 +184,14 @@ TEST_F( Albums, FetchAlbumFromTrack )
TEST_F( Albums, DestroyAlbum )
{
auto a = ml->createAlbum( "album" );
auto f = ml->addFile( "file.avi", nullptr );
auto t = a->addTrack( "track 1", 1 );
auto f = ml->addFile( "file.mp3", nullptr );
auto t = a->addTrack( f, 1 );
f->setAlbumTrack( t );
bool res = a->destroy();
ASSERT_TRUE( res );
f = std::static_pointer_cast<Media>( ml->file( "file.avi" ) );
f = std::static_pointer_cast<Media>( ml->file( "file.mp3" ) );
ASSERT_EQ( f, nullptr );
}
......
......@@ -98,30 +98,3 @@ TEST_F( Artists, GetAll )
auto artists2 = ml->artists();
ASSERT_EQ( artists2.size(), 5u );
}
TEST_F( Artists, UnknownArtist )
{
// If no song has been added, unknown artist should be null.
auto a = ml->unknownArtist();
ASSERT_EQ( a, nullptr );
auto album = ml->createAlbum( "Rise of the otters" );
auto t = album->addTrack( "Otters: awakening", 1 );
// explicitely set the artist to nullptr (aka "unknown artist")
auto res = t->addArtist( nullptr );
ASSERT_EQ( res, true );
// Now, querying unknownArtist should give out some results.
a = ml->unknownArtist();
ASSERT_NE( a, nullptr );
auto tracks = a->tracks();
ASSERT_EQ( tracks.size(), 1u );
Reload();
// Check that unknown artist tracks listing persists in DB
auto a2 = ml->unknownArtist();
ASSERT_NE( a2, nullptr );
auto tracks2 = a2->tracks();
ASSERT_EQ( tracks2.size(), 1u );
}
......@@ -24,6 +24,9 @@
#include "IMediaLibrary.h"
#include "Media.h"
#include "Artist.h"
#include "Album.h"
#include "AlbumTrack.h"
class Files : public Tests
{
......@@ -131,3 +134,93 @@ TEST_F( Files, Snapshot )
auto f2 = ml->file( "media.avi" );
ASSERT_EQ( f2->snapshot(), newSnapshot );
}
TEST_F( Files, UnknownArtist )
{
// If no song has been added, unknown artist should be null.
auto a = ml->unknownArtist();
ASSERT_EQ( a, nullptr );
auto f = ml->addFile( "file.mp3", nullptr );
// explicitely set the artist to nullptr (aka "unknown artist")
auto res = f->addArtist( nullptr );
ASSERT_EQ( res, true );
// Now, querying unknownArtist should give out some results.
a = ml->unknownArtist();
ASSERT_NE( a, nullptr );
auto tracks = a->media();
ASSERT_EQ( tracks.size(), 1u );
Reload();
// Check that unknown artist tracks listing persists in DB
auto a2 = ml->unknownArtist();
ASSERT_NE( a2, nullptr );
auto tracks2 = a2->media();
ASSERT_EQ( tracks2.size(), 1u );
}
TEST_F( Files, Artists )
{
auto artist1 = ml->createArtist( "artist 1" );
auto artist2 = ml->createArtist( "artist 2" );
auto album = ml->createAlbum( "album" );
ASSERT_NE( artist1, nullptr );
ASSERT_NE( artist2, nullptr );
for ( auto i = 1; i <= 3; i++ )
{
std::string name = "track" + std::to_string(i) + ".mp3";
auto f = ml->addFile( name, nullptr );
ASSERT_NE( f, nullptr );
auto t = album->addTrack( f, i );
ASSERT_NE( t, nullptr );
}
auto tracks = album->tracks();
for ( auto& it : tracks )
{
//FIXME: This should return a std::vector<IMedia>
auto t = std::static_pointer_cast<AlbumTrack>( it );
ASSERT_NE( t->files().size(), 0u );
for ( auto& it : t->files() )
{
auto f = std::static_pointer_cast<Media>( it );
auto res = f->addArtist( artist1 );
ASSERT_EQ( res, true );
res = f->addArtist( artist2 );
ASSERT_EQ( res, true );
auto artists = f->artists();
ASSERT_EQ( artists.size(), 2u );
}
}
auto artists = ml->artists();
for ( auto& a : artists )
{
auto media = a->media();
ASSERT_EQ( media.size(), 3u );
}
Reload();
auto album2 = ml->album( "album" );
auto tracks2 = album2->tracks();
for ( auto& t : tracks2 )
{
for ( auto& f : t->files() )
{
auto artists = f->artists();
ASSERT_EQ( artists.size(), 2u );
}
}
auto artists2 = ml->artists();
for ( auto& a : artists2 )
{
auto tracks = a->media();
ASSERT_EQ( tracks.size(), 3u );
}
}
......@@ -110,7 +110,7 @@ TEST_F( VLCMetadataServices, ParseAlbum )
ASSERT_NE( track, nullptr );
ASSERT_EQ( track->title(), "Mr. Zebra" );
ASSERT_EQ( track->genre(), "Rock" );
auto artists = track->artists();
auto artists = file->artists();
ASSERT_EQ( artists.size(), 1u );
ASSERT_EQ( artists[0]->name(), "Tori Amos" );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment