File indexing completed on 2024-04-28 04:48:06
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 "TestSingleCollectionTreeItemModel.h" 0018 0019 #include "amarokconfig.h" 0020 #include "core/meta/Meta.h" 0021 #include "browsers/CollectionTreeItemModelBase.h" 0022 #include "browsers/SingleCollectionTreeItemModel.h" 0023 0024 #include "CollectionTestImpl.h" 0025 #include "mocks/MockTrack.h" 0026 #include "mocks/MockAlbum.h" 0027 #include "mocks/MockArtist.h" 0028 0029 #include <QApplication> 0030 #include <QModelIndex> 0031 #include <QSet> 0032 #include <QSignalSpy> 0033 #include <QStringList> 0034 0035 #include <gmock/gmock.h> 0036 0037 using ::testing::Return; 0038 using ::testing::AnyNumber; 0039 using ::testing::_; 0040 0041 QTEST_MAIN( TestSingleCollectionTreeItemModel ) 0042 0043 void addMockTrack( Collections::CollectionTestImpl *coll, const QString &trackName, const QString &artistName, const QString &albumName ) 0044 { 0045 Meta::MockTrack *track = new Meta::MockTrack(); 0046 ::testing::Mock::AllowLeak( track ); 0047 Meta::TrackPtr trackPtr( track ); 0048 EXPECT_CALL( *track, name() ).Times( AnyNumber() ).WillRepeatedly( Return( trackName ) ); 0049 EXPECT_CALL( *track, prettyName() ).Times( AnyNumber() ).WillRepeatedly( Return( trackName ) ); 0050 EXPECT_CALL( *track, uidUrl() ).Times( AnyNumber() ).WillRepeatedly( Return( trackName + '_' + artistName + '_' + albumName ) ); 0051 EXPECT_CALL( *track, playableUrl() ).Times( AnyNumber() ).WillRepeatedly( Return( QUrl( '/' + track->uidUrl() ) ) ); 0052 EXPECT_CALL( *track, composer() ).Times( AnyNumber() ).WillRepeatedly( Return( Meta::ComposerPtr() ) ); 0053 EXPECT_CALL( *track, genre() ).Times( AnyNumber() ).WillRepeatedly( Return( Meta::GenrePtr() ) ); 0054 EXPECT_CALL( *track, year() ).Times( AnyNumber() ).WillRepeatedly( Return( Meta::YearPtr() ) ); 0055 coll->mc->addTrack( trackPtr ); 0056 0057 Meta::AlbumPtr albumPtr = coll->mc->albumMap().value( albumName, QString() /* no album artist */ ); 0058 Meta::MockAlbum *album; 0059 Meta::TrackList albumTracks; 0060 if( albumPtr ) 0061 { 0062 album = dynamic_cast<Meta::MockAlbum*>( albumPtr.data() ); 0063 if( !album ) 0064 { 0065 QFAIL( "expected a Meta::MockAlbum" ); 0066 return; 0067 } 0068 albumTracks = albumPtr->tracks(); 0069 } 0070 else 0071 { 0072 album = new Meta::MockAlbum(); 0073 ::testing::Mock::AllowLeak( album ); 0074 albumPtr = Meta::AlbumPtr( album ); 0075 EXPECT_CALL( *album, name() ).Times( AnyNumber() ).WillRepeatedly( Return( albumName ) ); 0076 EXPECT_CALL( *album, prettyName() ).Times( AnyNumber() ).WillRepeatedly( Return( albumName ) ); 0077 EXPECT_CALL( *album, hasAlbumArtist() ).Times( AnyNumber() ).WillRepeatedly( Return( false ) ); 0078 EXPECT_CALL( *album, isCompilation() ).Times( AnyNumber() ).WillRepeatedly( Return( false ) ); //inconsistent 0079 coll->mc->addAlbum( albumPtr ); 0080 } 0081 albumTracks << trackPtr; 0082 EXPECT_CALL( *album, tracks() ).Times( AnyNumber() ).WillRepeatedly( Return( albumTracks ) ); 0083 0084 EXPECT_CALL( *track, album() ).Times( AnyNumber() ).WillRepeatedly( Return( albumPtr ) ); 0085 0086 Meta::ArtistPtr artistPtr = coll->mc->artistMap().value( artistName ); 0087 Meta::MockArtist *artist; 0088 Meta::TrackList artistTracks; 0089 if( artistPtr ) 0090 { 0091 artist = dynamic_cast<Meta::MockArtist*>( artistPtr.data() ); 0092 if( !artist ) 0093 { 0094 QFAIL( "expected a Meta::MockArtist" ); 0095 return; 0096 } 0097 artistTracks = artistPtr->tracks(); 0098 } 0099 else 0100 { 0101 artist = new Meta::MockArtist(); 0102 ::testing::Mock::AllowLeak( artist ); 0103 artistPtr = Meta::ArtistPtr( artist ); 0104 EXPECT_CALL( *artist, name() ).Times( AnyNumber() ).WillRepeatedly( Return( artistName ) ); 0105 EXPECT_CALL( *artist, prettyName() ).Times( AnyNumber() ).WillRepeatedly( Return( artistName ) ); 0106 coll->mc->addArtist( artistPtr ); 0107 } 0108 artistTracks << trackPtr; 0109 EXPECT_CALL( *artist, tracks() ).Times( AnyNumber() ).WillRepeatedly( Return( artistTracks ) ); 0110 EXPECT_CALL( *track, artist() ).Times( AnyNumber() ).WillRepeatedly( Return( artistPtr ) ); 0111 EXPECT_CALL( *album, albumArtist() ).Times( AnyNumber() ).WillRepeatedly( Return( artistPtr ) ); 0112 } 0113 0114 void 0115 TestSingleCollectionTreeItemModel::initTestCase() 0116 { 0117 qRegisterMetaType<Meta::TrackList>(); 0118 qRegisterMetaType<Meta::AlbumList>(); 0119 qRegisterMetaType<Meta::ArtistList>(); 0120 qRegisterMetaType<Meta::DataList>(); 0121 qRegisterMetaType<Meta::GenreList>(); 0122 qRegisterMetaType<Meta::ComposerList>(); 0123 qRegisterMetaType<Meta::YearList>(); 0124 qRegisterMetaType<Meta::LabelList>(); 0125 0126 AmarokConfig::instance("amarokrc"); 0127 } 0128 0129 #define loadChildren( itemModel, idx ) \ 0130 { \ 0131 if( itemModel->canFetchMore( idx ) ) { \ 0132 QSignalSpy spy( itemModel, &SingleCollectionTreeItemModel::allQueriesFinished ); \ 0133 itemModel->fetchMore( idx ); \ 0134 QVERIFY( spy.wait( 5000 ) ); \ 0135 } \ 0136 } 0137 0138 void 0139 TestSingleCollectionTreeItemModel::testAddNewArtist() 0140 { 0141 Collections::CollectionTestImpl *coll = new Collections::CollectionTestImpl( "test" ); 0142 addMockTrack( coll, "track1", "artist1", "album1" ); 0143 0144 QList<CategoryId::CatMenuId> levels; 0145 levels<< CategoryId::Artist << CategoryId::Album; 0146 0147 SingleCollectionTreeItemModel *model = new SingleCollectionTreeItemModel( coll, levels ); 0148 0149 loadChildren( model, QModelIndex() ); 0150 0151 QCOMPARE( model->rowCount( QModelIndex() ), 1 ); 0152 0153 { 0154 QModelIndex artist1Index = model->index( 0, 0, QModelIndex() ); 0155 QCOMPARE( model->data( artist1Index, Qt::DisplayRole ).toString(), QString( "artist1" ) ); 0156 } 0157 0158 addMockTrack( coll, "track2", "artist2", "album2" ); 0159 0160 model->slotFilter(); 0161 0162 loadChildren( model, QModelIndex() ); 0163 0164 QCOMPARE( model->rowCount( QModelIndex() ), 2 ); 0165 0166 QSet<QString> artists; 0167 0168 QModelIndex idx1 = model->index( 0, 0, QModelIndex() ); 0169 artists << model->data( idx1, Qt::DisplayRole ).toString(); 0170 0171 QModelIndex idx2 = model->index( 1, 0, QModelIndex() ); 0172 artists << model->data( idx2, Qt::DisplayRole ).toString(); 0173 0174 { 0175 QSet<QString> expected; 0176 expected << "artist1" << "artist2"; 0177 QCOMPARE( artists, expected ); 0178 } 0179 0180 delete model; 0181 delete coll; 0182 } 0183 0184 void 0185 TestSingleCollectionTreeItemModel::testRemoveArtist() 0186 { 0187 Collections::CollectionTestImpl *coll = new Collections::CollectionTestImpl( "test" ); 0188 addMockTrack( coll, "track1", "artist1", "album1" ); 0189 addMockTrack( coll, "track2", "artist2", "album2" ); 0190 0191 QList<CategoryId::CatMenuId> levels; 0192 levels<< CategoryId::Artist << CategoryId::Album; 0193 0194 SingleCollectionTreeItemModel *model = new SingleCollectionTreeItemModel( coll, levels ); 0195 0196 loadChildren( model, QModelIndex() ); 0197 0198 QCOMPARE( model->rowCount( QModelIndex() ), 2 ); 0199 0200 { 0201 QSet<QString> artists; 0202 0203 QModelIndex idx1 = model->index( 0, 0, QModelIndex() ); 0204 artists << model->data( idx1, Qt::DisplayRole ).toString(); 0205 0206 QModelIndex idx2 = model->index( 1, 0, QModelIndex() ); 0207 artists << model->data( idx2, Qt::DisplayRole ).toString(); 0208 0209 QSet<QString> expected; 0210 expected << "artist1" << "artist2"; 0211 QCOMPARE( artists, expected ); 0212 } 0213 0214 ArtistMap map = coll->mc->artistMap(); 0215 map.remove( "artist2" ); //album and track are still part of the collection 0216 coll->mc->setArtistMap( map ); 0217 0218 model->slotFilter(); 0219 0220 loadChildren( model, QModelIndex() ); 0221 0222 QCOMPARE( model->rowCount( QModelIndex() ), 1 ); 0223 0224 { 0225 QModelIndex artist1Index = model->index( 0, 0, QModelIndex() ); 0226 QCOMPARE( model->data( artist1Index, Qt::DisplayRole ).toString(), QString( "artist1" ) ); 0227 } 0228 0229 delete model; 0230 delete coll; 0231 } 0232 0233 void 0234 TestSingleCollectionTreeItemModel::testAddTrack() 0235 { 0236 Collections::CollectionTestImpl *coll = new Collections::CollectionTestImpl( "test" ); 0237 addMockTrack( coll, "track1", "artist1", "album1" ); 0238 addMockTrack( coll, "track2", "artist2", "album2" ); 0239 0240 QList<CategoryId::CatMenuId> levels; 0241 levels<< CategoryId::Artist << CategoryId::Album; 0242 0243 SingleCollectionTreeItemModel *model = new SingleCollectionTreeItemModel( coll, levels ); 0244 0245 loadChildren( model, QModelIndex() ); 0246 0247 QCOMPARE( model->rowCount( QModelIndex() ), 2 ); 0248 0249 { 0250 QSet<QString> artists; 0251 0252 QModelIndex idx1 = model->index( 0, 0, QModelIndex() ); 0253 artists << model->data( idx1, Qt::DisplayRole ).toString(); 0254 0255 QModelIndex idx2 = model->index( 1, 0, QModelIndex() ); 0256 artists << model->data( idx2, Qt::DisplayRole ).toString(); 0257 0258 QSet<QString> expected; 0259 expected << "artist1" << "artist2"; 0260 QCOMPARE( artists, expected ); 0261 } 0262 0263 for( int i = 0; i < 2; i++ ) 0264 { 0265 QModelIndex parent = model->index( i, 0, QModelIndex() ); 0266 loadChildren( model, parent ); 0267 QCOMPARE( model->rowCount( parent ), 1 ); 0268 0269 QModelIndex subParent = model->index( 0, 0, parent ); 0270 loadChildren( model, subParent ); 0271 QCOMPARE( model->rowCount( subParent ), 1 ); 0272 } 0273 0274 addMockTrack( coll, "track3", "artist1", "album1" ); 0275 0276 model->slotFilter(); 0277 0278 QTest::qWait( 30 ); 0279 0280 loadChildren( model, QModelIndex() ); 0281 0282 QCOMPARE( model->rowCount( QModelIndex() ), 2 ); 0283 0284 for( int i = 0; i < 2; i++ ) 0285 { 0286 QModelIndex parent = model->index( i, 0, QModelIndex() ); 0287 loadChildren( model, parent ); 0288 QCOMPARE( model->rowCount( parent ), 1 ); 0289 0290 QString name = model->data( parent, Qt::DisplayRole ).toString(); 0291 int count = (name == "artist1" ? 2 : 1 ); 0292 0293 QModelIndex subParent = model->index( 0, 0, parent ); 0294 loadChildren( model, subParent ); 0295 QCOMPARE( model->rowCount( subParent ), count ); 0296 } 0297 0298 delete model; 0299 delete coll; 0300 } 0301 0302 void 0303 TestSingleCollectionTreeItemModel::testRemoveTrack() 0304 { 0305 0306 } 0307 0308 void 0309 TestSingleCollectionTreeItemModel::testAddTrackWithFilter() 0310 { 0311 Collections::CollectionTestImpl *coll = new Collections::CollectionTestImpl( "test" ); 0312 addMockTrack( coll, "track1", "artist1", "album1" ); 0313 0314 QList<CategoryId::CatMenuId> levels; 0315 levels << CategoryId::Artist << CategoryId::Album; 0316 0317 SingleCollectionTreeItemModel *model = new SingleCollectionTreeItemModel( coll, levels ); 0318 0319 loadChildren( model, QModelIndex() ); 0320 QCOMPARE( model->rowCount( QModelIndex() ), 1 ); 0321 0322 { 0323 QModelIndex artist1Index = model->index( 0, 0, QModelIndex() ); 0324 QCOMPARE( model->data( artist1Index, Qt::DisplayRole ).toString(), QString( "artist1" ) ); 0325 } 0326 0327 addMockTrack( coll, "track2", "artist2", "album2" ); 0328 model->setCurrentFilter( "track2" ); 0329 model->slotFilter(); 0330 loadChildren( model, QModelIndex() ); 0331 QCOMPARE( model->rowCount( QModelIndex() ), 1 ); 0332 0333 model->setCurrentFilter( QString() ); 0334 model->slotFilter(); 0335 loadChildren( model, QModelIndex() ); 0336 QCOMPARE( model->rowCount( QModelIndex() ), 2 ); 0337 0338 QModelIndex idx1 = model->index( 0, 0, QModelIndex() ); 0339 QCOMPARE( model->data( idx1, Qt::DisplayRole ).toString(), QString( "artist2" ) ); 0340 0341 delete model; 0342 delete coll; 0343 }