1 /* This file is part of Clementine.
2    Copyright 2010, David Sansome <me@davidsansome.com>
3 
4    Clementine is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation, either version 3 of the License, or
7    (at your option) any later version.
8 
9    Clementine is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License
15    along with Clementine.  If not, see <http://www.gnu.org/licenses/>.
16 */
17 
18 #include <memory>
19 
20 #include "core/encoding.h"
21 #include "core/mpris1.h"
22 #include "core/song.h"
23 #include "playlist/playlistmanager.h"
24 #include "playlist/playlistsequence.h"
25 #ifdef HAVE_LIBLASTFM
26   #include "internet/lastfm/lastfmcompat.h"
27 #endif
28 
29 #include "gmock/gmock.h"
30 #include "gtest/gtest.h"
31 
32 #include "test_utils.h"
33 #include "mock_engine.h"
34 #include "mock_player.h"
35 #include "mock_playlistmanager.h"
36 
37 #include <QDBusConnection>
38 #include <QDBusConnectionInterface>
39 #include <QSignalSpy>
40 #include <QTemporaryFile>
41 #include <QTextCodec>
42 
43 #include <id3v2tag.h>
44 
45 using ::testing::_;
46 using ::testing::Return;
47 
48 namespace {
49 
50 class Mpris1BasicTest : public ::testing::Test {
51 protected:
SetUp()52   void SetUp() {
53     sequence_.reset(new PlaylistSequence);
54 
55     EXPECT_CALL(player_, engine()).WillRepeatedly(Return(&engine_));
56     EXPECT_CALL(player_, playlists()).WillRepeatedly(Return(&playlists_));
57     EXPECT_CALL(playlists_, sequence()).WillRepeatedly(Return(sequence_.get()));
58   }
59 
service_name() const60   QString service_name() const {
61     return "org.clementine.unittest" +
62         QString::number(QCoreApplication::applicationPid());
63   }
64 
65   MockEngine engine_;
66   MockPlayer player_;
67   MockPlaylistManager playlists_;
68 
69   std::unique_ptr<PlaylistSequence> sequence_;
70 };
71 
TEST_F(Mpris1BasicTest,CreatesDBusService)72 TEST_F(Mpris1BasicTest, CreatesDBusService) {
73   EXPECT_FALSE(QDBusConnection::sessionBus().interface()->
74                isServiceRegistered(service_name()));
75 
76   std::unique_ptr<mpris::Mpris1> mpris(
77       new mpris::Mpris1(&player_, nullptr, nullptr, service_name()));
78   EXPECT_TRUE(QDBusConnection::sessionBus().interface()->
79               isServiceRegistered(service_name()));
80 
81   mpris.reset();
82   EXPECT_FALSE(QDBusConnection::sessionBus().interface()->
83                isServiceRegistered(service_name()));
84 }
85 
86 
87 class Mpris1Test : public Mpris1BasicTest {
88 protected:
SetUp()89   void SetUp() {
90     Mpris1BasicTest::SetUp();
91 
92     mpris_.reset(new mpris::Mpris1(&player_, nullptr, nullptr, service_name()));
93   }
94 
95   std::unique_ptr<mpris::Mpris1> mpris_;
96 };
97 
TEST_F(Mpris1Test,CorrectNameAndVersion)98 TEST_F(Mpris1Test, CorrectNameAndVersion) {
99   QCoreApplication::setApplicationName("Banana");
100   QCoreApplication::setApplicationVersion("Cheese");
101   EXPECT_EQ("Banana Cheese", mpris_->root()->Identity());
102 
103   Version version = mpris_->root()->MprisVersion();
104   EXPECT_EQ(1, version.major);
105   EXPECT_EQ(0, version.minor);
106 }
107 
TEST_F(Mpris1Test,Mutes)108 TEST_F(Mpris1Test, Mutes) {
109   EXPECT_CALL(player_, Mute());
110   mpris_->player()->Mute();
111 }
112 
TEST_F(Mpris1Test,GetsVolume)113 TEST_F(Mpris1Test, GetsVolume) {
114   EXPECT_CALL(player_, GetVolume()).WillOnce(Return(50));
115   EXPECT_EQ(50, mpris_->player()->VolumeGet());
116 }
117 
TEST_F(Mpris1Test,SetsVolume)118 TEST_F(Mpris1Test, SetsVolume) {
119   EXPECT_CALL(player_, SetVolume(42));
120   mpris_->player()->VolumeSet(42);
121 }
122 
TEST_F(Mpris1Test,RaisesVolume)123 TEST_F(Mpris1Test, RaisesVolume) {
124   EXPECT_CALL(player_, GetVolume()).WillOnce(Return(50));
125   EXPECT_CALL(player_, SetVolume(51));
126   mpris_->player()->VolumeUp(1);
127 }
128 
TEST_F(Mpris1Test,LowersVolume)129 TEST_F(Mpris1Test, LowersVolume) {
130   EXPECT_CALL(player_, GetVolume()).WillOnce(Return(50));
131   EXPECT_CALL(player_, SetVolume(49));
132   mpris_->player()->VolumeDown(1);
133 }
134 
TEST_F(Mpris1Test,Pauses)135 TEST_F(Mpris1Test, Pauses) {
136   EXPECT_CALL(player_, PlayPause());
137   mpris_->player()->Pause();
138 }
139 
TEST_F(Mpris1Test,Stops)140 TEST_F(Mpris1Test, Stops) {
141   EXPECT_CALL(player_, Stop());
142   mpris_->player()->Stop();
143 }
144 
TEST_F(Mpris1Test,Plays)145 TEST_F(Mpris1Test, Plays) {
146   EXPECT_CALL(player_, Play());
147   mpris_->player()->Play();
148 }
149 
TEST_F(Mpris1Test,GoesPrevious)150 TEST_F(Mpris1Test, GoesPrevious) {
151   EXPECT_CALL(player_, Previous());
152   mpris_->player()->Prev();
153 }
154 
TEST_F(Mpris1Test,GoesNext)155 TEST_F(Mpris1Test, GoesNext) {
156   EXPECT_CALL(player_, Next());
157   mpris_->player()->Next();
158 }
159 
TEST_F(Mpris1Test,SetsPosition)160 TEST_F(Mpris1Test, SetsPosition) {
161   EXPECT_CALL(player_, SeekTo(42));
162   mpris_->player()->PositionSet(42000);
163 }
164 
TEST_F(Mpris1Test,GetsStatus)165 TEST_F(Mpris1Test, GetsStatus) {
166   // Engine statuses
167   EXPECT_CALL(player_, GetState()).WillOnce(Return(Engine::Empty));
168   DBusStatus status = mpris_->player()->GetStatus();
169   EXPECT_EQ(DBusStatus::Mpris_Stopped, status.play);
170 
171   EXPECT_CALL(player_, GetState()).WillOnce(Return(Engine::Idle));
172   status = mpris_->player()->GetStatus();
173   EXPECT_EQ(DBusStatus::Mpris_Stopped, status.play);
174 
175   EXPECT_CALL(player_, GetState()).WillOnce(Return(Engine::Paused));
176   status = mpris_->player()->GetStatus();
177   EXPECT_EQ(DBusStatus::Mpris_Paused, status.play);
178 
179   EXPECT_CALL(player_, GetState()).WillOnce(Return(Engine::Playing));
180   status = mpris_->player()->GetStatus();
181   EXPECT_EQ(DBusStatus::Mpris_Playing, status.play);
182 
183   EXPECT_CALL(player_, GetState()).WillRepeatedly(Return(Engine::Empty));
184 
185   // Repeat modes
186   sequence_->SetRepeatMode(PlaylistSequence::Repeat_Off);
187   status = mpris_->player()->GetStatus();
188   EXPECT_EQ(0, status.repeat);
189   EXPECT_EQ(0, status.repeat_playlist);
190 
191   sequence_->SetRepeatMode(PlaylistSequence::Repeat_Album);
192   status = mpris_->player()->GetStatus();
193   EXPECT_EQ(0, status.repeat);
194   EXPECT_EQ(1, status.repeat_playlist);
195 
196   sequence_->SetRepeatMode(PlaylistSequence::Repeat_Playlist);
197   status = mpris_->player()->GetStatus();
198   EXPECT_EQ(0, status.repeat);
199   EXPECT_EQ(1, status.repeat_playlist);
200 
201   sequence_->SetRepeatMode(PlaylistSequence::Repeat_Track);
202   status = mpris_->player()->GetStatus();
203   EXPECT_EQ(1, status.repeat);
204   EXPECT_EQ(1, status.repeat_playlist);
205 
206   // Shuffle modes
207   sequence_->SetShuffleMode(PlaylistSequence::Shuffle_Off);
208   status = mpris_->player()->GetStatus();
209   EXPECT_EQ(0, status.random);
210 
211   sequence_->SetShuffleMode(PlaylistSequence::Shuffle_InsideAlbum);
212   status = mpris_->player()->GetStatus();
213   EXPECT_EQ(1, status.random);
214 
215   sequence_->SetShuffleMode(PlaylistSequence::Shuffle_Albums);
216   status = mpris_->player()->GetStatus();
217   EXPECT_EQ(1, status.random);
218 
219   sequence_->SetShuffleMode(PlaylistSequence::Shuffle_All);
220   status = mpris_->player()->GetStatus();
221   EXPECT_EQ(1, status.random);
222 }
223 
TEST_F(Mpris1Test,HandlesShuffleModeChanged)224 TEST_F(Mpris1Test, HandlesShuffleModeChanged) {
225   sequence_->SetShuffleMode(PlaylistSequence::Shuffle_Off);
226   EXPECT_CALL(player_, GetState()).WillRepeatedly(Return(Engine::Empty));
227 
228   QSignalSpy spy(mpris_->player(), SIGNAL(StatusChange(DBusStatus)));
229 
230   playlists_.EmitPlaylistManagerInitialized();
231   EXPECT_EQ(0, spy.count());
232 
233   sequence_->SetShuffleMode(PlaylistSequence::Shuffle_All);
234   ASSERT_EQ(1, spy.count());
235   EXPECT_EQ(1, spy[0][0].value<DBusStatus>().random);
236   spy.clear();
237 
238   sequence_->SetShuffleMode(PlaylistSequence::Shuffle_All);
239   ASSERT_EQ(0, spy.count());
240 
241   sequence_->SetShuffleMode(PlaylistSequence::Shuffle_InsideAlbum);
242   ASSERT_EQ(1, spy.count());
243   EXPECT_EQ(1, spy[0][0].value<DBusStatus>().random);
244   spy.clear();
245 
246   sequence_->SetShuffleMode(PlaylistSequence::Shuffle_Albums);
247   ASSERT_EQ(1, spy.count());
248   EXPECT_EQ(1, spy[0][0].value<DBusStatus>().random);
249   spy.clear();
250 
251   sequence_->SetShuffleMode(PlaylistSequence::Shuffle_Off);
252   ASSERT_EQ(1, spy.count());
253   EXPECT_EQ(0, spy[0][0].value<DBusStatus>().random);
254   spy.clear();
255 }
256 
257 }  // namespace
258 
259