File indexing completed on 2024-04-28 04:48:15

0001 /****************************************************************************************
0002  * Copyright (c) 2010 Maximilian Kossick <maximilian.kossick@googlemail.com>       *
0003  *                                                                                      *
0004  * This program is free software; you can redistribute it and/or modify it under        *
0005  * the terms of the GNU General Public License as published by the Free Software        *
0006  * Foundation; either version 2 of the License, or (at your option) any later           *
0007  * version.                                                                             *
0008  *                                                                                      *
0009  * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
0010  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
0011  * PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
0012  *                                                                                      *
0013  * You should have received a copy of the GNU General Public License along with         *
0014  * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
0015  ****************************************************************************************/
0016 
0017 #include "TestOneWaySynchronizationJob.h"
0018 
0019 #include "core/support/Debug.h"
0020 #include "core/collections/CollectionLocation.h"
0021 #include "synchronization/OneWaySynchronizationJob.h"
0022 
0023 #include "CollectionTestImpl.h"
0024 #include "mocks/MockTrack.h"
0025 #include "mocks/MockAlbum.h"
0026 #include "mocks/MockArtist.h"
0027 
0028 #include <gmock/gmock.h>
0029 
0030 #include <QSignalSpy>
0031 
0032 QTEST_GUILESS_MAIN( TestOneWaySynchronizationJob )
0033 
0034 using ::testing::Return;
0035 using ::testing::AnyNumber;
0036 
0037 
0038 static int trackCopyCount;
0039 
0040 namespace Collections {
0041 
0042 class MyCollectionLocation : public CollectionLocation
0043 {
0044 public:
0045     Collections::CollectionTestImpl *coll;
0046 
0047     QString prettyLocation() const override { return "foo"; }
0048     bool isWritable() const override { return true; }
0049     void copyUrlsToCollection(const QMap<Meta::TrackPtr, QUrl> &sources, const Transcoding::Configuration& conf) override
0050     {
0051         Q_UNUSED( conf )
0052         // qDebug() << "adding " << sources.count() << " tracks to " << coll->collectionId();
0053         trackCopyCount = sources.count();
0054         foreach( const Meta::TrackPtr &track, sources.keys() )
0055         {
0056             coll->mc->addTrack( track );
0057         }
0058     }
0059 };
0060 
0061 class MyCollectionTestImpl : public CollectionTestImpl
0062 {
0063 public:
0064     MyCollectionTestImpl( const QString &id ) : CollectionTestImpl( id ) {}
0065 
0066     CollectionLocation* location() override
0067     {
0068         MyCollectionLocation *r = new MyCollectionLocation();
0069         r->coll = this;
0070         return r;
0071     }
0072 };
0073 
0074 } //namespace Collections
0075 
0076 void addMockTrack( Collections::CollectionTestImpl *coll, const QString &trackName, const QString &artistName, const QString &albumName )
0077 {
0078     Meta::MockTrack *track = new Meta::MockTrack();
0079     ::testing::Mock::AllowLeak( track );
0080     Meta::TrackPtr trackPtr( track );
0081     EXPECT_CALL( *track, name() ).Times( AnyNumber() ).WillRepeatedly( Return( trackName ) );
0082     EXPECT_CALL( *track, uidUrl() ).Times( AnyNumber() ).WillRepeatedly( Return( trackName + '_' + artistName + '_' + albumName ) );
0083     EXPECT_CALL( *track, playableUrl() ).Times( AnyNumber() ).WillRepeatedly( Return( QUrl( '/' + track->uidUrl() ) ) );
0084     EXPECT_CALL( *track, composer() ).Times( AnyNumber() ).WillRepeatedly( Return( Meta::ComposerPtr() ) );
0085     EXPECT_CALL( *track, genre() ).Times( AnyNumber() ).WillRepeatedly( Return( Meta::GenrePtr() ) );
0086     EXPECT_CALL( *track, year() ).Times( AnyNumber() ).WillRepeatedly( Return( Meta::YearPtr() ) );
0087     coll->mc->addTrack( trackPtr );
0088 
0089     Meta::AlbumPtr albumPtr = coll->mc->albumMap().value( albumName, QString() /* no album artist */ );
0090     Meta::MockAlbum *album;
0091     Meta::TrackList albumTracks;
0092     if( albumPtr )
0093     {
0094         album = dynamic_cast<Meta::MockAlbum*>( albumPtr.data() );
0095         if( !album )
0096         {
0097             QFAIL( "expected a Meta::MockAlbum" );
0098             return;
0099         }
0100         albumTracks = albumPtr->tracks();
0101     }
0102     else
0103     {
0104         album = new Meta::MockAlbum();
0105         ::testing::Mock::AllowLeak( album );
0106         albumPtr = Meta::AlbumPtr( album );
0107         EXPECT_CALL( *album, name() ).Times( AnyNumber() ).WillRepeatedly( Return( albumName ) );
0108         EXPECT_CALL( *album, hasAlbumArtist() ).Times( AnyNumber() ).WillRepeatedly( Return( false ) );
0109         EXPECT_CALL( *album, albumArtist() ).Times( AnyNumber() ).WillRepeatedly( Return( Meta::ArtistPtr() ) );
0110         coll->mc->addAlbum( albumPtr );
0111     }
0112     albumTracks << trackPtr;
0113     EXPECT_CALL( *album, tracks() ).Times( AnyNumber() ).WillRepeatedly( Return( albumTracks ) );
0114 
0115     EXPECT_CALL( *track, album() ).Times( AnyNumber() ).WillRepeatedly( Return( albumPtr ) );
0116 
0117     Meta::ArtistPtr artistPtr = coll->mc->artistMap().value( artistName );
0118     Meta::MockArtist *artist;
0119     Meta::TrackList artistTracks;
0120     if( artistPtr )
0121     {
0122         artist = dynamic_cast<Meta::MockArtist*>( artistPtr.data() );
0123         if( !artist )
0124         {
0125             QFAIL( "expected a Meta::MockArtist" );
0126             return;
0127         }
0128         artistTracks = artistPtr->tracks();
0129     }
0130     else
0131     {
0132         artist = new Meta::MockArtist();
0133         ::testing::Mock::AllowLeak( artist );
0134         artistPtr = Meta::ArtistPtr( artist );
0135         EXPECT_CALL( *artist, name() ).Times( AnyNumber() ).WillRepeatedly( Return( artistName ) );
0136         coll->mc->addArtist( artistPtr );
0137     }
0138     artistTracks << trackPtr;
0139     EXPECT_CALL( *artist, tracks() ).Times( AnyNumber() ).WillRepeatedly( Return( artistTracks ) );
0140     EXPECT_CALL( *track, artist() ).Times( AnyNumber() ).WillRepeatedly( Return( artistPtr ) );
0141     EXPECT_CALL( *album, albumArtist() ).Times( AnyNumber() ).WillRepeatedly( Return( artistPtr ) );
0142 }
0143 
0144 TestOneWaySynchronizationJob::TestOneWaySynchronizationJob() : QObject()
0145 {
0146     int argc = 1;
0147     char **argv = (char **) malloc(sizeof(char *));
0148     argv[0] = strdup( QCoreApplication::applicationName().toLocal8Bit().data() );
0149     ::testing::InitGoogleMock( &argc, argv );
0150     qRegisterMetaType<Meta::TrackList>();
0151     qRegisterMetaType<Meta::AlbumList>();
0152     qRegisterMetaType<Meta::ArtistList>();
0153 }
0154 
0155 void
0156 TestOneWaySynchronizationJob::init()
0157 {
0158     trackCopyCount = 0;
0159 }
0160 
0161 void
0162 TestOneWaySynchronizationJob::testAddTrackToTarget()
0163 {
0164     Collections::CollectionTestImpl *source = new Collections::MyCollectionTestImpl( "source" );
0165     Collections::CollectionTestImpl *target = new Collections::MyCollectionTestImpl( "target" );
0166 
0167     addMockTrack( source, "track1", "artist1", "album1" );
0168     addMockTrack( source, "track2", "artist1", "album1" );
0169     addMockTrack( target, "track1", "artist1", "album1" );
0170 
0171     QCOMPARE( trackCopyCount, 0 );
0172     QCOMPARE( source->mc->trackMap().count(), 2 );
0173     QCOMPARE( target->mc->trackMap().count(), 1 );
0174 
0175     OneWaySynchronizationJob *job = new OneWaySynchronizationJob();
0176     QSignalSpy spy( job, &OneWaySynchronizationJob::destroyed );
0177     job->setSource( source );
0178     job->setTarget( target );
0179     job->synchronize();
0180     spy.wait( 1000 );
0181 
0182     QCOMPARE( trackCopyCount, 1 );
0183     QCOMPARE( source->mc->trackMap().count(), 2 );
0184     QCOMPARE( target->mc->trackMap().count(), 2 );
0185 
0186     delete source,
0187     delete target;
0188 }
0189 
0190 void
0191 TestOneWaySynchronizationJob::testAddAlbumToTarget()
0192 {
0193     Collections::CollectionTestImpl *source = new Collections::MyCollectionTestImpl( "source" );
0194     Collections::CollectionTestImpl *target = new Collections::MyCollectionTestImpl( "target" );
0195 
0196     addMockTrack( source, "track1", "artist1", "album1" );
0197     addMockTrack( source, "track1", "artist1", "album2" );
0198     addMockTrack( target, "track1", "artist1", "album1" );
0199 
0200     QCOMPARE( trackCopyCount, 0 );
0201     QCOMPARE( source->mc->trackMap().count(), 2 );
0202     QCOMPARE( target->mc->trackMap().count(), 1 );
0203 
0204     OneWaySynchronizationJob *job = new OneWaySynchronizationJob();
0205     QSignalSpy spy( job, &OneWaySynchronizationJob::destroyed );
0206     job->setSource( source );
0207     job->setTarget( target );
0208     job->synchronize();
0209     spy.wait( 1000 );
0210 
0211     QCOMPARE( trackCopyCount, 1 );
0212     QCOMPARE( source->mc->trackMap().count(), 2 );
0213     QCOMPARE( target->mc->trackMap().count(), 2 );
0214 
0215     delete source,
0216     delete target;
0217 }
0218 
0219 void
0220 TestOneWaySynchronizationJob::testAddArtistToTarget()
0221 {
0222     Collections::CollectionTestImpl *source = new Collections::MyCollectionTestImpl( "source" );
0223     Collections::CollectionTestImpl *target = new Collections::MyCollectionTestImpl( "target" );
0224 
0225     addMockTrack( source, "track1", "artist1", "album1" );
0226     addMockTrack( source, "track1", "artist2", "album1" );
0227     addMockTrack( target, "track1", "artist1", "album1" );
0228 
0229     QCOMPARE( trackCopyCount, 0 );
0230     QCOMPARE( source->mc->trackMap().count(), 2 );
0231     QCOMPARE( target->mc->trackMap().count(), 1 );
0232 
0233     OneWaySynchronizationJob *job = new OneWaySynchronizationJob();
0234     QSignalSpy spy( job, &OneWaySynchronizationJob::destroyed );
0235     job->setSource( source );
0236     job->setTarget( target );
0237     job->synchronize();
0238     spy.wait( 1000 );
0239 
0240     QCOMPARE( trackCopyCount, 1 );
0241     QCOMPARE( source->mc->trackMap().count(), 2 );
0242     QCOMPARE( target->mc->trackMap().count(), 2 );
0243 
0244     delete source,
0245     delete target;
0246 }
0247 
0248 void
0249 TestOneWaySynchronizationJob::testEmptyTarget()
0250 {
0251     Collections::CollectionTestImpl *source = new Collections::MyCollectionTestImpl( "source" );
0252     Collections::CollectionTestImpl *target = new Collections::MyCollectionTestImpl( "target" );
0253 
0254     addMockTrack( source, "track1", "artist1", "album1" );
0255     addMockTrack( source, "track2", "artist1", "album1" );
0256 
0257     QCOMPARE( trackCopyCount, 0 );
0258     QCOMPARE( source->mc->trackMap().count(), 2 );
0259     QCOMPARE( target->mc->trackMap().count(), 0 );
0260 
0261     OneWaySynchronizationJob *job = new OneWaySynchronizationJob();
0262     QSignalSpy spy( job, &OneWaySynchronizationJob::destroyed );
0263     job->setSource( source );
0264     job->setTarget( target );
0265     job->synchronize();
0266     spy.wait( 1000 );
0267 
0268     QCOMPARE( trackCopyCount, 2 );
0269     QCOMPARE( source->mc->trackMap().count(), 2 );
0270     QCOMPARE( target->mc->trackMap().count(), 2 );
0271 
0272     delete source,
0273     delete target;
0274 }
0275 
0276 void
0277 TestOneWaySynchronizationJob::testEmptySourceWithNonEmptyTarget()
0278 {
0279     Collections::CollectionTestImpl *source = new Collections::MyCollectionTestImpl( "source" );
0280     Collections::CollectionTestImpl *target = new Collections::MyCollectionTestImpl( "target" );
0281 
0282     addMockTrack( target, "track1", "artist1", "album1" );
0283 
0284     QCOMPARE( trackCopyCount, 0 );
0285     QCOMPARE( source->mc->trackMap().count(), 0 );
0286     QCOMPARE( target->mc->trackMap().count(), 1 );
0287 
0288     OneWaySynchronizationJob *job = new OneWaySynchronizationJob();
0289     QSignalSpy spy( job, &OneWaySynchronizationJob::destroyed );
0290     job->setSource( source );
0291     job->setTarget( target );
0292     job->synchronize();
0293     spy.wait( 1000 );
0294 
0295     QCOMPARE( trackCopyCount, 0 );
0296     QCOMPARE( source->mc->trackMap().count(), 0 );
0297     QCOMPARE( target->mc->trackMap().count(), 1 );
0298 
0299     delete source,
0300     delete target;
0301 }
0302 
0303 void
0304 TestOneWaySynchronizationJob::testNoActionNecessary()
0305 {
0306     Collections::CollectionTestImpl *source = new Collections::MyCollectionTestImpl( "source" );
0307     Collections::CollectionTestImpl *target = new Collections::MyCollectionTestImpl( "target" );
0308 
0309     addMockTrack( source, "track1", "artist1", "album1" );
0310     addMockTrack( source, "track2", "artist1", "album1" );
0311     addMockTrack( target, "track1", "artist1", "album1" );
0312     addMockTrack( target, "track2", "artist1", "album1" );
0313 
0314     QCOMPARE( trackCopyCount, 0 );
0315     QCOMPARE( source->mc->trackMap().count(), 2 );
0316     QCOMPARE( target->mc->trackMap().count(), 2 );
0317 
0318     OneWaySynchronizationJob *job = new OneWaySynchronizationJob();
0319     QSignalSpy spy( job, &OneWaySynchronizationJob::destroyed );
0320     job->setSource( source );
0321     job->setTarget( target );
0322     job->synchronize();
0323     spy.wait( 1000 );
0324 
0325     QCOMPARE( trackCopyCount, 0 );
0326     QCOMPARE( source->mc->trackMap().count(), 2 );
0327     QCOMPARE( target->mc->trackMap().count(), 2 );
0328 
0329     delete source,
0330     delete target;
0331 }