File indexing completed on 2024-04-28 04:48:13
0001 /**************************************************************************************** 0002 * Copyright (c) 2013 Konrad Zemek <konrad.zemek@gmail.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 <TestImporterBase.h> 0018 0019 #include "MetaValues.h" 0020 #include "core/meta/support/MetaConstants.h" 0021 #include "statsyncing/Provider.h" 0022 #include "statsyncing/Track.h" 0023 0024 #include <QTest> 0025 0026 0027 using namespace StatSyncing; 0028 0029 TestImporterBase::TestImporterBase() 0030 { 0031 } 0032 0033 ProviderPtr 0034 TestImporterBase::getWritableProvider() 0035 { 0036 return getProvider(); 0037 } 0038 0039 bool 0040 TestImporterBase::hasOddRatings() const 0041 { 0042 return true; 0043 } 0044 0045 #define skipIfNoSupport( fieldmask, metavalue ) \ 0046 { \ 0047 if( !( fieldmask & metavalue ) ) \ 0048 { \ 0049 const QString msg = QString( "Tested provider does not support %1 metadata" ) \ 0050 .arg( Meta::nameForField( metavalue ) ); \ 0051 QSKIP( msg.toLocal8Bit().constData(), SkipAll ); \ 0052 } \ 0053 } do {} while(false) 0054 0055 #define amarokProviderSkipIfNoMysqld( provider ) \ 0056 if( QString( provider->prettyName() ) == "Amarok2Test" ) \ 0057 if( !QFileInfo( "/usr/bin/mysqld" ).isExecutable() ) \ 0058 QSKIP( "/usr/bin/mysqld not executable, skipping Amarok provider tests", \ 0059 SkipAll ) 0060 0061 void 0062 TestImporterBase::titleShouldBeCaseSensitive() 0063 { 0064 ProviderPtr provider( getProvider() ); 0065 amarokProviderSkipIfNoMysqld( provider ); 0066 0067 const QString artist = "caseSensitiveTitle"; 0068 QVERIFY( provider->artists().contains( artist ) ); 0069 0070 QSet<QString> trackNames; 0071 foreach( const TrackPtr &track, provider->artistTracks( artist ) ) 0072 trackNames.insert( track->name() ); 0073 0074 QCOMPARE( trackNames.size(), 3 ); 0075 QVERIFY( trackNames.contains( "title" ) ); 0076 QVERIFY( trackNames.contains( "Title" ) ); 0077 QVERIFY( trackNames.contains( "tiTle" ) ); 0078 } 0079 0080 void 0081 TestImporterBase::artistShouldBeCaseSensitive() 0082 { 0083 ProviderPtr provider( getProvider() ); 0084 amarokProviderSkipIfNoMysqld( provider ); 0085 0086 const QVector<QString> artists = QVector<QString>() 0087 << "caseSensitiveArtist" << "casesensitiveartist" << "caseSensitiveartist"; 0088 0089 foreach( const QString &artist, artists ) 0090 { 0091 const TrackList tracks = provider->artistTracks( artist ); 0092 QCOMPARE( tracks.size(), 1 ); 0093 QCOMPARE( tracks.front()->artist(), artist ); 0094 } 0095 } 0096 0097 void 0098 TestImporterBase::albumShouldBeCaseSensitive() 0099 { 0100 ProviderPtr provider( getProvider() ); 0101 amarokProviderSkipIfNoMysqld( provider ); 0102 0103 const QString artist = "caseSensitiveAlbum"; 0104 QVERIFY( provider->artists().contains( artist ) ); 0105 0106 QSet<QString> trackAlbums; 0107 foreach( const TrackPtr &track, provider->artistTracks( artist ) ) 0108 trackAlbums.insert( track->album() ); 0109 0110 QCOMPARE( trackAlbums.size(), 3 ); 0111 QVERIFY( trackAlbums.contains( "album" ) ); 0112 QVERIFY( trackAlbums.contains( "Album" ) ); 0113 QVERIFY( trackAlbums.contains( "alBum" ) ); 0114 } 0115 0116 void 0117 TestImporterBase::composerShouldBeCaseSensitive() 0118 { 0119 ProviderPtr provider( getProvider() ); 0120 amarokProviderSkipIfNoMysqld( provider ); 0121 skipIfNoSupport( provider->reliableTrackMetaData(), Meta::valComposer ); 0122 0123 const QString artist = "caseSensitiveComposer"; 0124 QVERIFY( provider->artists().contains( artist ) ); 0125 0126 QSet<QString> trackComposers; 0127 foreach( const TrackPtr &track, provider->artistTracks( artist ) ) 0128 trackComposers.insert( track->composer() ); 0129 0130 QCOMPARE( trackComposers.size(), 3 ); 0131 QVERIFY( trackComposers.contains( "composer" ) ); 0132 QVERIFY( trackComposers.contains( "Composer" ) ); 0133 QVERIFY( trackComposers.contains( "comPoser" ) ); 0134 } 0135 0136 void 0137 TestImporterBase::titleShouldSupportUTF() 0138 { 0139 ProviderPtr provider( getProvider() ); 0140 amarokProviderSkipIfNoMysqld( provider ); 0141 0142 const QString artist = "utfTitle"; 0143 QVERIFY( provider->artists().contains( artist ) ); 0144 0145 const TrackList tracks = provider->artistTracks( artist ); 0146 QCOMPARE( tracks.size(), 1 ); 0147 QCOMPARE( tracks.front()->name(), QString::fromWCharArray( L"\xF906\xF907\xF908" ) ); 0148 } 0149 0150 void 0151 TestImporterBase::artistShouldSupportUTF() 0152 { 0153 ProviderPtr provider( getProvider() ); 0154 amarokProviderSkipIfNoMysqld( provider ); 0155 0156 const QString artist = QString::fromWCharArray( L"utf\xF909\xF90A\xF90B" ); 0157 QVERIFY( provider->artists().contains( artist ) ); 0158 0159 const TrackList tracks = provider->artistTracks( artist ); 0160 QCOMPARE( tracks.size(), 1 ); 0161 QCOMPARE( tracks.front()->artist(), artist ); 0162 } 0163 0164 void 0165 TestImporterBase::albumShouldSupportUTF() 0166 { 0167 ProviderPtr provider( getProvider() ); 0168 amarokProviderSkipIfNoMysqld( provider ); 0169 0170 const QString artist = "utfAlbum"; 0171 QVERIFY( provider->artists().contains( artist ) ); 0172 0173 const TrackList tracks = provider->artistTracks( artist ); 0174 QCOMPARE( tracks.size(), 1 ); 0175 QCOMPARE( tracks.front()->album(), QString::fromWCharArray( L"\xF903\xF904\xF905" ) ); 0176 } 0177 0178 void 0179 TestImporterBase::composerShouldSupportUTF() 0180 { 0181 ProviderPtr provider( getProvider() ); 0182 amarokProviderSkipIfNoMysqld( provider ); 0183 skipIfNoSupport( provider->reliableTrackMetaData(), Meta::valComposer ); 0184 0185 const QString artist = "utfComposer"; 0186 QVERIFY( provider->artists().contains( artist ) ); 0187 0188 const TrackList tracks = provider->artistTracks( artist ); 0189 QCOMPARE( tracks.size(), 1 ); 0190 QCOMPARE( tracks.front()->composer(), 0191 QString::fromWCharArray( L"\xF900\xF901\xF902" ) ); 0192 } 0193 0194 void 0195 TestImporterBase::titleShouldSupportMultipleWords() 0196 { 0197 ProviderPtr provider( getProvider() ); 0198 amarokProviderSkipIfNoMysqld( provider ); 0199 0200 const QString artist = "multiWordTitle"; 0201 QVERIFY( provider->artists().contains( artist ) ); 0202 0203 const TrackList tracks = provider->artistTracks( artist ); 0204 QCOMPARE( tracks.size(), 1 ); 0205 QCOMPARE( tracks.front()->name(), QString( "ti tl e" ) ); 0206 } 0207 0208 void 0209 TestImporterBase::artistShouldSupportMultipleWords() 0210 { 0211 ProviderPtr provider( getProvider() ); 0212 amarokProviderSkipIfNoMysqld( provider ); 0213 0214 const QString artist = "multi Word Artist"; 0215 QVERIFY( provider->artists().contains( artist ) ); 0216 0217 const TrackList tracks = provider->artistTracks( artist ); 0218 QCOMPARE( tracks.size(), 1 ); 0219 QCOMPARE( tracks.front()->artist(), artist ); 0220 } 0221 0222 void 0223 TestImporterBase::albumShouldSupportMultipleWords() 0224 { 0225 ProviderPtr provider( getProvider() ); 0226 amarokProviderSkipIfNoMysqld( provider ); 0227 0228 const QString artist = "multiWordAlbum"; 0229 QVERIFY( provider->artists().contains( artist ) ); 0230 0231 const TrackList tracks = provider->artistTracks( artist ); 0232 QCOMPARE( tracks.size(), 1 ); 0233 QCOMPARE( tracks.front()->album(), QString( "al b um" ) ); 0234 } 0235 0236 void 0237 TestImporterBase::composerShouldSupportMultipleWords() 0238 { 0239 ProviderPtr provider( getProvider() ); 0240 amarokProviderSkipIfNoMysqld( provider ); 0241 skipIfNoSupport( provider->reliableTrackMetaData(), Meta::valComposer ); 0242 0243 const QString artist = "multiWordComposer"; 0244 QVERIFY( provider->artists().contains( artist ) ); 0245 0246 const TrackList tracks = provider->artistTracks( artist ); 0247 QCOMPARE( tracks.size(), 1 ); 0248 QCOMPARE( tracks.front()->composer(), QString( "com po ser" ) ); 0249 } 0250 0251 void 0252 TestImporterBase::titleShouldBeWhitespaceTrimmed() 0253 { 0254 ProviderPtr provider( getProvider() ); 0255 amarokProviderSkipIfNoMysqld( provider ); 0256 0257 const QString artist = "trimTitle"; 0258 QVERIFY( provider->artists().contains( artist ) ); 0259 0260 QSet<QString> trackNames; 0261 foreach( const TrackPtr &track, provider->artistTracks( artist ) ) 0262 trackNames.insert( track->name() ); 0263 0264 QCOMPARE( trackNames.size(), 3 ); 0265 QVERIFY( trackNames.contains( "title1" ) ); 0266 QVERIFY( trackNames.contains( "title2" ) ); 0267 QVERIFY( trackNames.contains( "title3" ) ); 0268 } 0269 0270 void 0271 TestImporterBase::artistShouldBeWhitespaceTrimmed() 0272 { 0273 ProviderPtr provider( getProvider() ); 0274 amarokProviderSkipIfNoMysqld( provider ); 0275 0276 const QString artist = "trimArtist"; 0277 QVERIFY( provider->artists().contains( artist ) ); 0278 0279 const TrackList tracks = provider->artistTracks( artist ); 0280 QCOMPARE( tracks.size(), 3 ); 0281 0282 foreach( const TrackPtr &track, tracks ) 0283 QCOMPARE( track->artist(), artist ); 0284 } 0285 0286 void 0287 TestImporterBase::albumShouldBeWhitespaceTrimmed() 0288 { 0289 ProviderPtr provider( getProvider() ); 0290 amarokProviderSkipIfNoMysqld( provider ); 0291 0292 const QString artist = "trimAlbum"; 0293 QVERIFY( provider->artists().contains( artist ) ); 0294 0295 const TrackList tracks = provider->artistTracks( artist ); 0296 QCOMPARE( tracks.size(), 3 ); 0297 0298 foreach( const TrackPtr &track, tracks ) 0299 QCOMPARE( track->album(), QString( "album" ) ); 0300 } 0301 0302 void 0303 TestImporterBase::composerShouldBeWhitespaceTrimmed() 0304 { 0305 ProviderPtr provider( getProvider() ); 0306 amarokProviderSkipIfNoMysqld( provider ); 0307 skipIfNoSupport( provider->reliableTrackMetaData(), Meta::valComposer ); 0308 0309 const QString artist = "trimComposer"; 0310 QVERIFY( provider->artists().contains( artist ) ); 0311 0312 const TrackList tracks = provider->artistTracks( artist ); 0313 QCOMPARE( tracks.size(), 3 ); 0314 0315 foreach( const TrackPtr &track, tracks ) 0316 QCOMPARE( track->composer(), QString( "composer" ) ); 0317 } 0318 0319 void 0320 TestImporterBase::albumShouldBeUnsetIfTagIsUnset() 0321 { 0322 ProviderPtr provider( getProvider() ); 0323 amarokProviderSkipIfNoMysqld( provider ); 0324 0325 const QString artist = "albumUnset"; 0326 QVERIFY( provider->artists().contains( artist ) ); 0327 0328 const TrackList tracks = provider->artistTracks( artist ); 0329 QCOMPARE( tracks.size(), 1 ); 0330 QCOMPARE( tracks.front()->album(), QString() ); 0331 } 0332 0333 void 0334 TestImporterBase::composerShouldBeUnsetIfTagIsUnset() 0335 { 0336 ProviderPtr provider( getProvider() ); 0337 amarokProviderSkipIfNoMysqld( provider ); 0338 skipIfNoSupport( provider->reliableTrackMetaData(), Meta::valComposer ); 0339 0340 const QString artist = "composerUnset"; 0341 QVERIFY( provider->artists().contains( artist ) ); 0342 0343 const TrackList tracks = provider->artistTracks( artist ); 0344 QCOMPARE( tracks.size(), 1 ); 0345 QCOMPARE( tracks.front()->composer(), QString() ); 0346 } 0347 0348 void 0349 TestImporterBase::yearShouldBeUnsetIfTagIsUnset() 0350 { 0351 ProviderPtr provider( getProvider() ); 0352 amarokProviderSkipIfNoMysqld( provider ); 0353 skipIfNoSupport( provider->reliableTrackMetaData(), Meta::valYear ); 0354 0355 const QString artist = "yearUnset"; 0356 QVERIFY( provider->artists().contains( artist ) ); 0357 0358 const TrackList tracks = provider->artistTracks( artist ); 0359 QCOMPARE( tracks.size(), 1 ); 0360 QCOMPARE( tracks.front()->year(), 0 ); 0361 } 0362 0363 void 0364 TestImporterBase::trackShouldBeUnsetIfTagIsUnset() 0365 { 0366 ProviderPtr provider( getProvider() ); 0367 amarokProviderSkipIfNoMysqld( provider ); 0368 skipIfNoSupport( provider->reliableTrackMetaData(), Meta::valTrackNr ); 0369 0370 const QString artist = "trackUnset"; 0371 QVERIFY( provider->artists().contains( artist ) ); 0372 0373 const TrackList tracks = provider->artistTracks( artist ); 0374 QCOMPARE( tracks.size(), 1 ); 0375 QCOMPARE( tracks.front()->trackNumber(), 0 ); 0376 } 0377 0378 void 0379 TestImporterBase::discShouldBeUnsetIfTagIsUnset() 0380 { 0381 ProviderPtr provider( getProvider() ); 0382 amarokProviderSkipIfNoMysqld( provider ); 0383 skipIfNoSupport( provider->reliableTrackMetaData(), Meta::valDiscNr ); 0384 0385 const QString artist = "discUnset"; 0386 QVERIFY( provider->artists().contains( artist ) ); 0387 0388 const TrackList tracks = provider->artistTracks( artist ); 0389 QCOMPARE( tracks.size(), 1 ); 0390 QCOMPARE( tracks.front()->discNumber(), 0 ); 0391 } 0392 0393 void 0394 TestImporterBase::checkStatistics( const QString &artist ) 0395 { 0396 ProviderPtr provider( getProvider() ); 0397 amarokProviderSkipIfNoMysqld( provider ); 0398 QVERIFY( provider->artists().contains( artist ) ); 0399 0400 QMap<QString, TrackPtr> trackForName; 0401 foreach( const TrackPtr &track, provider->artistTracks( artist ) ) 0402 trackForName.insert( track->name(), track ); 0403 0404 const QString testName( QTest::currentDataTag() ); 0405 QCOMPARE( trackForName.size(), 10 ); 0406 QVERIFY( trackForName.contains( testName ) ); 0407 0408 const TrackPtr &track = trackForName.value( testName ); 0409 0410 if( reliableStatistics() & Meta::valFirstPlayed ) 0411 QTEST( track->firstPlayed(), "firstPlayed" ); 0412 if( reliableStatistics() & Meta::valLastPlayed ) 0413 QTEST( track->lastPlayed(), "lastPlayed" ); 0414 if( reliableStatistics() & Meta::valPlaycount ) 0415 QTEST( track->playCount(), "playCount" ); 0416 0417 if( reliableStatistics() & Meta::valRating ) 0418 { 0419 QFETCH( int, rating ); 0420 if( !hasOddRatings() && (rating & 1) ) 0421 ++rating; 0422 0423 QCOMPARE( track->rating(), rating ); 0424 } 0425 } 0426 0427 void 0428 TestImporterBase::tracksShouldHaveStatistics_data() 0429 { 0430 QTest::addColumn<QDateTime> ( "firstPlayed" ); 0431 QTest::addColumn<QDateTime> ( "lastPlayed" ); 0432 QTest::addColumn<int> ( "rating" ); 0433 QTest::addColumn<int> ( "playCount" ); 0434 0435 QVector<QDateTime> d; 0436 for( uint t = 0; t < 20; ++t ) 0437 d.push_back( QDateTime::fromSecsSinceEpoch( 1378125780u + t ) ); 0438 0439 QTest::newRow( "title0" ) << d[ 0] << d[ 1] << 1 << 20; 0440 QTest::newRow( "title1" ) << d[ 2] << d[ 3] << 2 << 15; 0441 QTest::newRow( "title2" ) << d[ 4] << d[ 5] << 3 << 14; 0442 QTest::newRow( "title3" ) << d[ 6] << d[ 7] << 4 << 13; 0443 QTest::newRow( "title4" ) << d[ 8] << d[ 9] << 5 << 11; 0444 QTest::newRow( "title5" ) << d[10] << d[11] << 6 << 10; 0445 QTest::newRow( "title6" ) << d[12] << d[13] << 7 << 7; 0446 QTest::newRow( "title7" ) << d[14] << d[15] << 8 << 5; 0447 QTest::newRow( "title8" ) << d[16] << d[17] << 9 << 3; 0448 QTest::newRow( "title9" ) << d[18] << d[19] << 10 << 2; 0449 } 0450 0451 void 0452 TestImporterBase::tracksShouldHaveStatistics() 0453 { 0454 checkStatistics( "testStatistics" ); 0455 } 0456 0457 void 0458 TestImporterBase::tracksShouldBehaveNicelyWithNoStatistics_data() 0459 { 0460 QTest::addColumn<QDateTime> ( "firstPlayed" ); 0461 QTest::addColumn<QDateTime> ( "lastPlayed" ); 0462 QTest::addColumn<int> ( "rating" ); 0463 QTest::addColumn<int> ( "playCount" ); 0464 0465 QVector<QDateTime> d; 0466 for( uint t = 0; t < 20; ++t ) 0467 d.push_back( QDateTime::fromSecsSinceEpoch( 1378125780u + t ) ); 0468 0469 QTest::newRow( "title0" ) << QDateTime() << QDateTime() << 0 << 0; 0470 QTest::newRow( "title1" ) << QDateTime() << d[ 3] << 2 << 15; 0471 QTest::newRow( "title2" ) << QDateTime() << QDateTime() << 3 << 14; 0472 QTest::newRow( "title3" ) << QDateTime() << d[ 7] << 0 << 13; 0473 QTest::newRow( "title4" ) << QDateTime() << QDateTime() << 5 << 0; 0474 QTest::newRow( "title5" ) << d[10] << d[11] << 6 << 10; 0475 QTest::newRow( "title6" ) << d[12] << QDateTime() << 0 << 7; 0476 QTest::newRow( "title7" ) << d[14] << d[15] << 8 << 5; 0477 QTest::newRow( "title8" ) << d[16] << QDateTime() << 9 << 0; 0478 QTest::newRow( "title9" ) << d[18] << d[19] << 0 << 2; 0479 } 0480 0481 void 0482 TestImporterBase::tracksShouldBehaveNicelyWithNoStatistics() 0483 { 0484 checkStatistics( "testStatisticsNotSet" ); 0485 } 0486 0487 void TestImporterBase::labels( const ProviderPtr &provider, const QString &trackName ) 0488 { 0489 m_lbl.clear(); 0490 0491 const QString artist = "testStatistics"; 0492 0493 QVERIFY( provider->artists().contains( artist ) ); 0494 0495 QMap<QString, TrackPtr> trackForName; 0496 foreach( const TrackPtr &track, provider->artistTracks( artist ) ) 0497 { 0498 QVERIFY( !trackForName.contains( track->name() ) ); 0499 trackForName.insert( track->name(), track ); 0500 } 0501 0502 QVERIFY( trackForName.contains( trackName ) ); 0503 m_lbl = trackForName.value( trackName )->labels(); 0504 } 0505 0506 void 0507 TestImporterBase::tracksShouldWorkWithSingleLabel() 0508 { 0509 ProviderPtr provider( getProvider() ); 0510 amarokProviderSkipIfNoMysqld( provider ); 0511 skipIfNoSupport( reliableStatistics(), Meta::valLabel ); 0512 0513 labels( provider, "title0" ); 0514 0515 QCOMPARE( m_lbl.size(), 1 ); 0516 QVERIFY( m_lbl.contains( "singleTag" ) ); 0517 } 0518 0519 void 0520 TestImporterBase::tracksShouldWorkWithMultipleLabels() 0521 { 0522 ProviderPtr provider( getProvider() ); 0523 amarokProviderSkipIfNoMysqld( provider ); 0524 skipIfNoSupport( reliableStatistics(), Meta::valLabel ); 0525 0526 labels( provider, "title1" ); 0527 0528 QCOMPARE( m_lbl.size(), 2 ); 0529 QVERIFY( m_lbl.contains( "multiple" ) ); 0530 QVERIFY( m_lbl.contains( "tags" ) ); 0531 } 0532 0533 void 0534 TestImporterBase::tracksShouldWorkWithCaseSensitiveLabels() 0535 { 0536 ProviderPtr provider( getProvider() ); 0537 amarokProviderSkipIfNoMysqld( provider ); 0538 skipIfNoSupport( reliableStatistics(), Meta::valLabel ); 0539 0540 labels( provider, "title2" ); 0541 0542 QCOMPARE( m_lbl.size(), 2 ); 0543 QVERIFY( m_lbl.contains( "caseSensitive" ) ); 0544 QVERIFY( m_lbl.contains( "casesensitive" ) ); 0545 } 0546 0547 void 0548 TestImporterBase::tracksShouldWorkWithUTFLabels() 0549 { 0550 ProviderPtr provider( getProvider() ); 0551 amarokProviderSkipIfNoMysqld( provider ); 0552 skipIfNoSupport( reliableStatistics(), Meta::valLabel ); 0553 0554 labels( provider, "title3" ); 0555 0556 QCOMPARE( m_lbl.size(), 1 ); 0557 QVERIFY( m_lbl.contains( QString::fromWCharArray( L"\x2622" ) ) ); 0558 } 0559 0560 void 0561 TestImporterBase::providerShouldReturnNoTracksForNonexistentArtist() 0562 { 0563 ProviderPtr provider( getProvider() ); 0564 amarokProviderSkipIfNoMysqld( provider ); 0565 0566 const QString artist = "I'mNotHere"; 0567 QVERIFY( !provider->artists().contains( artist ) ); 0568 QVERIFY( provider->artistTracks( artist ).isEmpty() ); 0569 } 0570 0571 void 0572 TestImporterBase::providerShouldNotBreakOnLittleBobbyTables() 0573 { 0574 ProviderPtr provider( getProvider() ); 0575 amarokProviderSkipIfNoMysqld( provider ); 0576 0577 const QString artist = "Robert'); DROP TABLE students;--"; 0578 QVERIFY( !provider->artists().contains( artist ) ); 0579 QVERIFY( provider->artistTracks( artist ).isEmpty() ); 0580 } 0581 0582 static TrackPtr 0583 trackForName( ProviderPtr &provider, const QString &name, const QString &artist ) 0584 { 0585 foreach( const TrackPtr &track, provider->artistTracks( artist ) ) 0586 if( track->name() == name ) 0587 return track; 0588 0589 return TrackPtr( nullptr ); 0590 } 0591 0592 static Meta::FieldHash 0593 saveData( const TrackPtr &track ) 0594 { 0595 Meta::FieldHash data; 0596 data.insert( Meta::valTitle, track->name() ); 0597 data.insert( Meta::valArtist, track->artist() ); 0598 data.insert( Meta::valAlbum, track->album() ); 0599 data.insert( Meta::valComposer, track->composer() ); 0600 data.insert( Meta::valTrackNr, track->trackNumber() ); 0601 data.insert( Meta::valDiscNr, track->discNumber() ); 0602 data.insert( Meta::valFirstPlayed, track->firstPlayed() ); 0603 data.insert( Meta::valLastPlayed, track->lastPlayed() ); 0604 data.insert( Meta::valRating, track->rating() ); 0605 data.insert( Meta::valPlaycount, track->playCount() ); 0606 data.insert( Meta::valLabel, QStringList( track->labels().values() ) ); 0607 return data; 0608 } 0609 0610 static void 0611 verifyEqualExcept( const Meta::FieldHash &lhs, const TrackPtr &track, 0612 const qint64 except ) 0613 { 0614 const QList<qint64> fields = QList<qint64>() << Meta::valTitle << Meta::valArtist 0615 << Meta::valAlbum << Meta::valComposer << Meta::valTrackNr 0616 << Meta::valDiscNr << Meta::valFirstPlayed 0617 << Meta::valLastPlayed << Meta::valRating 0618 << Meta::valPlaycount << Meta::valLabel; 0619 0620 const Meta::FieldHash rhs = saveData( track ); 0621 foreach( const qint64 field, fields ) 0622 if( !( except & field ) ) 0623 QCOMPARE( lhs.value( field ), rhs.value( field ) ); 0624 } 0625 0626 void 0627 TestImporterBase::commitAfterSettingAllStatisticsShouldSaveThem_data() 0628 { 0629 QTest::addColumn<QString>( "title" ); 0630 QTest::addColumn<QString>( "artist" ); 0631 QTest::addColumn<QDateTime>( "newFirstPlayed" ); 0632 QTest::addColumn<QDateTime>( "newLastPlayed" ); 0633 QTest::addColumn<int>( "newRating" ); 0634 QTest::addColumn<int>( "newPlayCount" ); 0635 QTest::addColumn<QStringList>( "newLabels" ); 0636 0637 const uint now = QDateTime::currentDateTimeUtc().toSecsSinceEpoch(); 0638 0639 QTest::newRow( "Replace all" ) << "title0" << "testStatistics" 0640 << QDateTime::fromSecsSinceEpoch( now - 100 ) 0641 << QDateTime::fromSecsSinceEpoch( now + 100 ) 0642 << 9 << 25 << ( QStringList() << "teh" << "lab'ls" ); 0643 0644 QTest::newRow( "Add all" ) << "title0" << "testStatisticsNotSet" 0645 << QDateTime::fromSecsSinceEpoch( now - 100 ) 0646 << QDateTime::fromSecsSinceEpoch(now + 100 ) 0647 << 9 << 25 << ( QStringList() << "teh" << "lab'ls" ); 0648 0649 QTest::newRow( "Add some 1" ) << "title2" << "testStatisticsNotSet" 0650 << QDateTime::fromSecsSinceEpoch( now - 100 ) 0651 << QDateTime::fromSecsSinceEpoch( now + 100 ) 0652 << 9 << 25 << ( QStringList() << "teh" << "lab'ls" ); 0653 0654 QTest::newRow( "Add some 1" ) << "title4" << "testStatisticsNotSet" 0655 << QDateTime::fromSecsSinceEpoch( now - 100 ) 0656 << QDateTime::fromSecsSinceEpoch( now + 100 ) 0657 << 9 << 25 << ( QStringList() << "teh" << "lab'ls" ); 0658 0659 QTest::newRow( "Add some 1" ) << "title6" << "testStatisticsNotSet" 0660 << QDateTime::fromSecsSinceEpoch( now - 100 ) 0661 << QDateTime::fromSecsSinceEpoch( now + 100 ) 0662 << 9 << 25 << ( QStringList() << "teh" << "lab'ls" ); 0663 } 0664 0665 void 0666 TestImporterBase::commitAfterSettingAllStatisticsShouldSaveThem() 0667 { 0668 ProviderPtr provider( getWritableProvider() ); 0669 amarokProviderSkipIfNoMysqld( provider ); 0670 0671 QFETCH( QString, title ); 0672 QFETCH( QString, artist ); 0673 TrackPtr track = trackForName( provider, title, artist ); 0674 QVERIFY( track ); 0675 0676 const Meta::FieldHash data = saveData( track ); 0677 0678 if( provider->writableTrackStatsData() & Meta::valFirstPlayed ) 0679 { 0680 QFETCH( QDateTime, newFirstPlayed ); 0681 track->setFirstPlayed( newFirstPlayed ); 0682 } 0683 if( provider->writableTrackStatsData() & Meta::valLastPlayed ) 0684 { 0685 QFETCH( QDateTime, newLastPlayed ); 0686 track->setLastPlayed( newLastPlayed ); 0687 } 0688 if( provider->writableTrackStatsData() & Meta::valRating ) 0689 { 0690 QFETCH( int, newRating ); 0691 track->setRating( newRating ); 0692 } 0693 if( provider->writableTrackStatsData() & Meta::valPlaycount ) 0694 { 0695 QFETCH( int, newPlayCount ); 0696 track->setPlayCount( newPlayCount ); 0697 } 0698 if( provider->writableTrackStatsData() & Meta::valLabel ) 0699 { 0700 QFETCH( QStringList, newLabels ); 0701 track->setLabels( newLabels.toSet() ); 0702 } 0703 0704 track->commit(); 0705 provider->commitTracks(); 0706 0707 track = trackForName( provider, title, artist ); 0708 QVERIFY( track ); 0709 0710 if( provider->writableTrackStatsData() & Meta::valFirstPlayed ) 0711 { 0712 QFETCH( QDateTime, newFirstPlayed ); 0713 QCOMPARE( track->firstPlayed(), newFirstPlayed ); 0714 } 0715 if( provider->writableTrackStatsData() & Meta::valLastPlayed ) 0716 { 0717 QFETCH( QDateTime, newLastPlayed ); 0718 QCOMPARE( track->lastPlayed(), newLastPlayed ); 0719 } 0720 if( provider->writableTrackStatsData() & Meta::valRating ) 0721 { 0722 QFETCH( int, newRating ); 0723 if( !hasOddRatings() && (newRating & 1) ) 0724 ++newRating; 0725 QCOMPARE( track->rating(), newRating ); 0726 } 0727 if( provider->writableTrackStatsData() & Meta::valPlaycount ) 0728 { 0729 QFETCH( int, newPlayCount ); 0730 QCOMPARE( track->playCount(), newPlayCount ); 0731 } 0732 if( provider->writableTrackStatsData() & Meta::valLabel ) 0733 { 0734 QFETCH( QStringList, newLabels ); 0735 QCOMPARE( track->labels(), newLabels.toSet() ); 0736 } 0737 0738 verifyEqualExcept( data, track, Meta::valFirstPlayed | Meta::valLastPlayed | 0739 Meta::valRating | Meta::valPlaycount | Meta::valLabel ); 0740 } 0741 0742 void 0743 TestImporterBase::commitAfterSettingFirstPlayedShouldSaveIt_data() 0744 { 0745 QTest::addColumn<QString>( "title" ); 0746 QTest::addColumn<QDateTime>( "newFirstPlayed" ); 0747 0748 const uint now = QDateTime::currentDateTimeUtc().toSecsSinceEpoch(); 0749 0750 QTest::newRow( "Add stat 1" ) << "title0" << QDateTime::fromSecsSinceEpoch( now ); 0751 QTest::newRow( "Add stat 2" ) << "title1" << QDateTime::fromSecsSinceEpoch( now + 2 ); 0752 QTest::newRow( "Add stat 3" ) << "title2" << QDateTime::fromSecsSinceEpoch( now + 3 ); 0753 0754 QTest::newRow( "Replace stat 1" ) << "title5" << QDateTime::fromSecsSinceEpoch( now + 11 ); 0755 QTest::newRow( "Replace stat 2" ) << "title6" << QDateTime::fromSecsSinceEpoch( now + 13 ); 0756 QTest::newRow( "Replace stat 3" ) << "title7" << QDateTime::fromSecsSinceEpoch( now + 17 ); 0757 0758 QTest::newRow( "Remove stat 1" ) << "title5" << QDateTime(); 0759 QTest::newRow( "Remove stat 2" ) << "title6" << QDateTime(); 0760 QTest::newRow( "Remove stat 3" ) << "title7" << QDateTime(); 0761 } 0762 0763 void 0764 TestImporterBase::commitAfterSettingFirstPlayedShouldSaveIt() 0765 { 0766 ProviderPtr provider( getWritableProvider() ); 0767 amarokProviderSkipIfNoMysqld( provider ); 0768 skipIfNoSupport( provider->writableTrackStatsData(), Meta::valFirstPlayed ); 0769 0770 QFETCH( QString, title ); 0771 QFETCH( QDateTime, newFirstPlayed ); 0772 0773 TrackPtr track = trackForName( provider, title, "testStatisticsNotSet" ); 0774 QVERIFY( track ); 0775 0776 const Meta::FieldHash data = saveData( track ); 0777 track->setFirstPlayed( newFirstPlayed ); 0778 track->commit(); 0779 provider->commitTracks(); 0780 0781 track = trackForName( provider, title, "testStatisticsNotSet" ); 0782 QVERIFY( track ); 0783 QCOMPARE( track->firstPlayed(), newFirstPlayed ); 0784 verifyEqualExcept( data, track, Meta::valFirstPlayed ); 0785 } 0786 0787 void 0788 TestImporterBase::commitAfterSettingLastPlayedShouldSaveIt_data() 0789 { 0790 QTest::addColumn<QString>( "title" ); 0791 QTest::addColumn<QDateTime>( "newLastPlayed" ); 0792 0793 const uint now = QDateTime::currentDateTimeUtc().toSecsSinceEpoch(); 0794 0795 QTest::newRow( "Add stat 1" ) << "title0" << QDateTime::fromSecsSinceEpoch( now ); 0796 QTest::newRow( "Add stat 2" ) << "title2" << QDateTime::fromSecsSinceEpoch( now + 2 ); 0797 QTest::newRow( "Add stat 3" ) << "title4" << QDateTime::fromSecsSinceEpoch( now + 3 ); 0798 0799 QTest::newRow( "Replace stat 1" ) << "title1" << QDateTime::fromSecsSinceEpoch( now + 11 ); 0800 QTest::newRow( "Replace stat 2" ) << "title3" << QDateTime::fromSecsSinceEpoch( now + 13 ); 0801 QTest::newRow( "Replace stat 3" ) << "title5" << QDateTime::fromSecsSinceEpoch( now + 17 ); 0802 0803 QTest::newRow( "Remove stat 1" ) << "title1" << QDateTime(); 0804 QTest::newRow( "Remove stat 2" ) << "title3" << QDateTime(); 0805 QTest::newRow( "Remove stat 3" ) << "title5" << QDateTime(); 0806 } 0807 0808 void 0809 TestImporterBase::commitAfterSettingLastPlayedShouldSaveIt() 0810 { 0811 ProviderPtr provider( getWritableProvider() ); 0812 amarokProviderSkipIfNoMysqld( provider ); 0813 skipIfNoSupport( provider->writableTrackStatsData(), Meta::valLastPlayed ); 0814 0815 QFETCH( QString, title ); 0816 QFETCH( QDateTime, newLastPlayed ); 0817 0818 TrackPtr track = trackForName( provider, title, "testStatisticsNotSet" ); 0819 QVERIFY( track ); 0820 0821 const Meta::FieldHash data = saveData( track ); 0822 track->setLastPlayed( newLastPlayed ); 0823 track->commit(); 0824 provider->commitTracks(); 0825 0826 track = trackForName( provider, title, "testStatisticsNotSet" ); 0827 QVERIFY( track ); 0828 QCOMPARE( track->lastPlayed(), newLastPlayed ); 0829 verifyEqualExcept( data, track, Meta::valLastPlayed ); 0830 } 0831 0832 void 0833 TestImporterBase::commitAfterSettingRatingShouldSaveIt_data() 0834 { 0835 QTest::addColumn<QString>( "title" ); 0836 QTest::addColumn<int>( "newRating" ); 0837 0838 QTest::newRow( "Add stat 1" ) << "title0" << 2; 0839 QTest::newRow( "Add stat 2" ) << "title3" << 3; 0840 QTest::newRow( "Add stat 3" ) << "title6" << 5; 0841 0842 QTest::newRow( "Replace stat 1" ) << "title1" << 1; 0843 QTest::newRow( "Replace stat 2" ) << "title2" << 3; 0844 QTest::newRow( "Replace stat 3" ) << "title4" << 6; 0845 0846 QTest::newRow( "Remove stat 1" ) << "title1" << 0; 0847 QTest::newRow( "Remove stat 2" ) << "title2" << 0; 0848 QTest::newRow( "Remove stat 3" ) << "title4" << 0; 0849 } 0850 0851 void 0852 TestImporterBase::commitAfterSettingRatingShouldSaveIt() 0853 { 0854 ProviderPtr provider( getWritableProvider() ); 0855 amarokProviderSkipIfNoMysqld( provider ); 0856 skipIfNoSupport( provider->writableTrackStatsData(), Meta::valRating ); 0857 0858 QFETCH( QString, title ); 0859 QFETCH( int, newRating ); 0860 0861 TrackPtr track = trackForName( provider, title, "testStatisticsNotSet" ); 0862 QVERIFY( track ); 0863 0864 const Meta::FieldHash data = saveData( track ); 0865 track->setRating( newRating ); 0866 track->commit(); 0867 provider->commitTracks(); 0868 0869 if( !hasOddRatings() && (newRating & 1) ) 0870 ++newRating; 0871 0872 track = trackForName( provider, title, "testStatisticsNotSet" ); 0873 QVERIFY( track ); 0874 QCOMPARE( track->rating(), newRating ); 0875 verifyEqualExcept( data, track, Meta::valRating ); 0876 } 0877 0878 void 0879 TestImporterBase::commitAfterSettingPlaycountShouldSaveIt_data() 0880 { 0881 QTest::addColumn<QString>( "title" ); 0882 QTest::addColumn<int>( "newPlayCount" ); 0883 0884 QTest::newRow( "Add stat 1" ) << "title0" << 13; 0885 QTest::newRow( "Add stat 2" ) << "title4" << 17; 0886 QTest::newRow( "Add stat 3" ) << "title8" << 23; 0887 0888 QTest::newRow( "Replace stat 1" ) << "title1" << 1; 0889 QTest::newRow( "Replace stat 2" ) << "title2" << 3; 0890 QTest::newRow( "Replace stat 3" ) << "title3" << 6; 0891 0892 QTest::newRow( "Remove stat 1" ) << "title1" << 0; 0893 QTest::newRow( "Remove stat 2" ) << "title2" << 0; 0894 QTest::newRow( "Remove stat 3" ) << "title3" << 0; 0895 } 0896 0897 void 0898 TestImporterBase::commitAfterSettingPlaycountShouldSaveIt() 0899 { 0900 ProviderPtr provider( getWritableProvider() ); 0901 amarokProviderSkipIfNoMysqld( provider ); 0902 skipIfNoSupport( provider->writableTrackStatsData(), Meta::valPlaycount ); 0903 0904 QFETCH( QString, title ); 0905 QFETCH( int, newPlayCount ); 0906 0907 TrackPtr track = trackForName( provider, title, "testStatisticsNotSet" ); 0908 QVERIFY( track ); 0909 0910 const Meta::FieldHash data = saveData( track ); 0911 track->setPlayCount( newPlayCount ); 0912 track->commit(); 0913 provider->commitTracks(); 0914 0915 track = trackForName( provider, title, "testStatisticsNotSet" ); 0916 QVERIFY( track ); 0917 QCOMPARE( track->playCount(), newPlayCount ); 0918 verifyEqualExcept( data, track, Meta::valPlaycount ); 0919 } 0920 0921 void 0922 TestImporterBase::commitAfterSettingLabelsShouldSaveThem_data() 0923 { 0924 QTest::addColumn<QString>( "title" ); 0925 QTest::addColumn<QStringList>( "newLabels" ); 0926 0927 QTest::newRow( "Add new label" ) << "title4" << ( QStringList() << "singleTag2" ); 0928 QTest::newRow( "Add existing label" ) << "title5" << ( QStringList() << "singleTag" ); 0929 QTest::newRow( "Add labels" ) << "title6" << ( QStringList() << "multi" << "labels" ); 0930 QTest::newRow( "Add existing labels" ) << "title7" 0931 << ( QStringList() << "multiple" << "labels" ); 0932 QTest::newRow( "Add case-sensitive labels" ) << "title8" 0933 << ( QStringList() << "cs" << "Cs" ); 0934 0935 QTest::newRow( "Replace all labels" ) << "title1" << ( QStringList() << "a" << "l" ); 0936 QTest::newRow( "Replace some labels" ) << "title1" 0937 << ( QStringList() << "a" << "tags" ); 0938 QTest::newRow( "Add additional labels" ) << "title1" 0939 << ( QStringList() << "multiple" << "tags" << "2" ); 0940 0941 QTest::newRow( "Remove labels 1" ) << "title0" << QStringList(); 0942 QTest::newRow( "Remove labels 2" ) << "title1" << QStringList(); 0943 QTest::newRow( "Remove labels 3" ) << "title2" << QStringList(); 0944 } 0945 0946 void 0947 TestImporterBase::commitAfterSettingLabelsShouldSaveThem() 0948 { 0949 ProviderPtr provider( getWritableProvider() ); 0950 amarokProviderSkipIfNoMysqld( provider ); 0951 skipIfNoSupport( provider->writableTrackStatsData(), Meta::valLabel ); 0952 0953 QFETCH( QString, title ); 0954 QFETCH( QStringList, newLabels ); 0955 0956 TrackPtr track = trackForName( provider, title, "testStatistics" ); 0957 QVERIFY( track ); 0958 0959 const Meta::FieldHash data = saveData( track ); 0960 track->setLabels( newLabels.toSet() ); 0961 track->commit(); 0962 provider->commitTracks(); 0963 0964 track = trackForName( provider, title, "testStatistics" ); 0965 QVERIFY( track ); 0966 QCOMPARE( track->labels(), newLabels.toSet() ); 0967 verifyEqualExcept( data, track, Meta::valLabel ); 0968 }