File indexing completed on 2024-06-16 04:32:38

0001 /***************************************************************************
0002  *   Copyright (c) 2009 Sven Krohlas <sven@asbest-online.de>               *
0003  *                                                                         *
0004  *   This program is free software; you can redistribute it and/or modify  *
0005  *   it under the terms of the GNU General Public License as published by  *
0006  *   the Free Software Foundation; either version 2 of the License, or     *
0007  *   (at your option) any later version.                                   *
0008  *                                                                         *
0009  *   This program is distributed in the hope that it will be useful,       *
0010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0012  *   GNU General Public License for more details.                          *
0013  *                                                                         *
0014  *   You should have received a copy of the GNU General Public License     *
0015  *   along with this program; if not, write to the                         *
0016  *   Free Software Foundation, Inc.,                                       *
0017  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
0018  ***************************************************************************/
0019 
0020 #include "TestMetaMultiTrack.h"
0021 
0022 #include "core/support/Components.h"
0023 #include "EngineController.h"
0024 #include "config-amarok-test.h"
0025 #include "core-impl/collections/support/CollectionManager.h"
0026 #include "core-impl/meta/multi/MultiTrack.h"
0027 #include "core-impl/playlists/types/file/PlaylistFileSupport.h"
0028 
0029 #include <QDir>
0030 #include <QFileInfo>
0031 #include <QSignalSpy>
0032 #include <QTest>
0033 #include <QTimer>
0034 
0035 #include <ThreadWeaver/Queue>
0036 
0037 QTEST_GUILESS_MAIN( TestMetaMultiTrack )
0038 
0039 TestMetaMultiTrack::TestMetaMultiTrack()
0040     : m_testMultiTrack( nullptr )
0041 {
0042 }
0043 
0044 void
0045 TestMetaMultiTrack::tracksLoaded( Playlists::PlaylistPtr playlist )
0046 {
0047     emit tracksLoadedSignal( playlist );
0048 }
0049 
0050 void TestMetaMultiTrack::initTestCase()
0051 {
0052     qRegisterMetaType<Meta::TrackPtr>( "Meta::TrackPtr" );
0053 
0054     //apparently the engine controller is needed somewhere, or we will get a crash...
0055     EngineController *controller = new EngineController();
0056     Amarok::Components::setEngineController( controller );
0057 
0058     /* Collection manager needs to be instantiated in the main thread, but
0059      * MetaProxy::Tracks used by playlist may trigger its creation in a different thread.
0060      * Pre-create it explicitly */
0061     CollectionManager::instance();
0062 
0063     const QString path = QString( AMAROK_TEST_DIR ) + "/data/playlists/test.pls";
0064     const QFileInfo file( QDir::toNativeSeparators( path ) );
0065     QVERIFY( file.exists() );
0066     const QString filePath = file.absoluteFilePath();
0067     m_playlist = Playlists::loadPlaylistFile( QUrl::fromLocalFile(filePath) ).data();
0068     QVERIFY( m_playlist ); // no playlist -> no test. that's life ;)
0069     subscribeTo( m_playlist );
0070     m_playlist->triggerTrackLoad();
0071     QSignalSpy spy( this, &TestMetaMultiTrack::tracksLoadedSignal );
0072     if( m_playlist->trackCount() < 0 )
0073         QVERIFY( spy.wait( 5000 ) );
0074 
0075     QCOMPARE( m_playlist->name(), QString("test.pls") );
0076     QCOMPARE( m_playlist->trackCount(), 4 );
0077 
0078     // now wait for all MetaProxy::Tracks to actually load their real tracks:
0079     NotifyObserversWaiter wainter( m_playlist->tracks().toSet() );
0080     QSignalSpy spyDone( &wainter, &NotifyObserversWaiter::done );
0081     QVERIFY( spyDone.wait( 5000 ) );
0082 }
0083 
0084 void
0085 TestMetaMultiTrack::cleanupTestCase()
0086 {
0087     // Wait for other jobs, like MetaProxys fetching meta data, to finish
0088     ThreadWeaver::Queue::instance()->finish();
0089 }
0090 
0091 void TestMetaMultiTrack::init()
0092 {
0093     m_testMultiTrack = new Meta::MultiTrack( m_playlist );
0094 }
0095 
0096 void TestMetaMultiTrack::cleanup()
0097 {
0098     delete m_testMultiTrack;
0099 }
0100 
0101 void TestMetaMultiTrack::testSources()
0102 {
0103     QStringList sources = m_testMultiTrack->sources();
0104     QCOMPARE( sources.size(), 4 );
0105     QCOMPARE( sources.at( 0 ), QString( "http://85.214.44.27:8000" ) );
0106     QCOMPARE( sources.at( 1 ), QString( "http://217.20.121.40:8000" ) );
0107     QCOMPARE( sources.at( 2 ), QString( "http://85.214.44.27:8100" ) );
0108     QCOMPARE( sources.at( 3 ), QString( "http://85.214.44.27:8200" ) );
0109 }
0110 
0111 void TestMetaMultiTrack::testSetSourceCurrentNextUrl()
0112 {
0113     QCOMPARE( m_testMultiTrack->current(), 0 );
0114     QCOMPARE( m_testMultiTrack->playableUrl(), QUrl("http://85.214.44.27:8000") );
0115     QCOMPARE( m_testMultiTrack->nextUrl(), QUrl("http://217.20.121.40:8000") );
0116 
0117     m_testMultiTrack->setSource( 1 );
0118     QCOMPARE( m_testMultiTrack->current(), 1 );
0119     QCOMPARE( m_testMultiTrack->playableUrl(), QUrl("http://217.20.121.40:8000") );
0120     QCOMPARE( m_testMultiTrack->nextUrl(), QUrl("http://85.214.44.27:8100") );
0121 
0122     m_testMultiTrack->setSource( 2 );
0123     QCOMPARE( m_testMultiTrack->current(), 2 );
0124     QCOMPARE( m_testMultiTrack->playableUrl(), QUrl("http://85.214.44.27:8100") );
0125     QCOMPARE( m_testMultiTrack->nextUrl(), QUrl("http://85.214.44.27:8200") );
0126 
0127     m_testMultiTrack->setSource( 3 );
0128     QCOMPARE( m_testMultiTrack->current(), 3 );
0129     QCOMPARE( m_testMultiTrack->playableUrl(), QUrl("http://85.214.44.27:8200") );
0130     QCOMPARE( m_testMultiTrack->nextUrl(), QUrl() );
0131 
0132     m_testMultiTrack->setSource( 4 );
0133     QCOMPARE( m_testMultiTrack->current(), 3 );
0134     m_testMultiTrack->setSource( -1 );
0135     QCOMPARE( m_testMultiTrack->current(), 3 );
0136 }
0137 
0138 void TestMetaMultiTrack::testHasCapabilityInterface()
0139 {
0140     QVERIFY( m_testMultiTrack->hasCapabilityInterface( Capabilities::Capability::MultiSource ) );
0141 }
0142 
0143 NotifyObserversWaiter::NotifyObserversWaiter( const QSet<Meta::TrackPtr> &tracks, QObject *parent )
0144     : QObject( parent )
0145     , m_tracks( tracks )
0146 {
0147     // we need to filter already resolved tracks in the next event loop iteration because
0148     // the user wouldn't be able to get the done() signal yet.
0149     QTimer::singleShot( 0, this, &NotifyObserversWaiter::slotFilterResolved );
0150 }
0151 
0152 void
0153 NotifyObserversWaiter::slotFilterResolved()
0154 {
0155     QMutexLocker locker( &m_mutex );
0156     QMutableSetIterator<Meta::TrackPtr> it( m_tracks );
0157     while( it.hasNext() )
0158     {
0159         const Meta::TrackPtr &track = it.next();
0160         const MetaProxy::Track *proxyTrack = dynamic_cast<const MetaProxy::Track *>( track.data() );
0161         Q_ASSERT( proxyTrack );
0162         if( proxyTrack->isResolved() )
0163             it.remove();
0164         else
0165             subscribeTo( track );
0166     }
0167     if( m_tracks.isEmpty() )
0168         emit done();
0169 }
0170 
0171 void
0172 NotifyObserversWaiter::metadataChanged( Meta::TrackPtr track )
0173 {
0174     QMutexLocker locker( &m_mutex );
0175     m_tracks.remove( track );
0176     if( m_tracks.isEmpty() )
0177         emit done();
0178 }