1 #include <tests/lib/test.h>
2
3 #include <tests/lib/glib-helpers/test-conn-helper.h>
4
5 #include <tests/lib/glib/simple-conn.h>
6 #include <tests/lib/glib/captcha-chan.h>
7
8 #include <TelepathyQt/Captcha>
9 #include <TelepathyQt/CaptchaAuthentication>
10 #include <TelepathyQt/Connection>
11 #include <TelepathyQt/PendingReady>
12 #include <TelepathyQt/PendingCaptchas>
13 #include <TelepathyQt/ReferencedHandles>
14 #include <TelepathyQt/ServerAuthenticationChannel>
15
16 #include <telepathy-glib/telepathy-glib.h>
17
18 #include <stdio.h>
19
20 using namespace Tp;
21
22 class TestCaptchaAuthentication : public Test
23 {
24 Q_OBJECT
25
26 public:
TestCaptchaAuthentication(QObject * parent=0)27 TestCaptchaAuthentication(QObject *parent = 0)
28 : Test(parent),
29 mConn(0), mChanService(0)
30 { }
31
32 private Q_SLOTS:
33 void initTestCase();
34 void init();
35
36 void testCreation();
37 void testCaptchaSuccessful();
38 void testCaptchaRetry();
39 void testCaptchaCancel();
40 void testNoCaptcha();
41
42 void cleanup();
43 void cleanupTestCase();
44
45 private:
46 void createCaptchaChannel(bool canRetry = false);
47
48 TestConnHelper *mConn;
49 TpTestsCaptchaChannel *mChanService;
50 ServerAuthenticationChannelPtr mChan;
51 CaptchaAuthenticationPtr mCaptcha;
52 };
53
createCaptchaChannel(bool canRetry)54 void TestCaptchaAuthentication::createCaptchaChannel(bool canRetry)
55 {
56 mChan.reset();
57 mLoop->processEvents();
58 tp_clear_object(&mChanService);
59
60 /* Create service-side tube channel object */
61 QString chanPath = QString(QLatin1String("%1/Channel")).arg(mConn->objectPath());
62
63 mChanService = TP_TESTS_CAPTCHA_CHANNEL(g_object_new(
64 TP_TESTS_TYPE_CAPTCHA_CHANNEL,
65 "connection", mConn->service(),
66 "requested", FALSE,
67 "object-path", chanPath.toLatin1().constData(),
68 "can-retry-captcha", canRetry,
69 NULL));
70
71 /* Create client-side tube channel object */
72 mChan = ServerAuthenticationChannel::create(mConn->client(), chanPath, QVariantMap());
73
74 // Verify features shouldn't be Ready
75 QVERIFY(mChan->captchaAuthentication().isNull());
76 QVERIFY(!mChan->hasCaptchaInterface());
77 //QVERIFY(!mChan->hasSaslInterface());
78
79 QVERIFY(connect(mChan->becomeReady(ServerAuthenticationChannel::FeatureCore),
80 SIGNAL(finished(Tp::PendingOperation *)),
81 SLOT(expectSuccessfulCall(Tp::PendingOperation *))));
82 QCOMPARE(mLoop->exec(), 0);
83
84 QVERIFY(mChan->isReady(ServerAuthenticationChannel::FeatureCore));
85 QVERIFY(mChan->hasCaptchaInterface());
86 //QVERIFY(!mChan->hasSaslInterface());
87
88 mCaptcha = mChan->captchaAuthentication();
89
90 QCOMPARE(mCaptcha.isNull(), false);
91 }
92
initTestCase()93 void TestCaptchaAuthentication::initTestCase()
94 {
95 initTestCaseImpl();
96
97 g_type_init();
98 g_set_prgname("captcha-authentication");
99 tp_debug_set_flags("all");
100 dbus_g_bus_get(DBUS_BUS_STARTER, 0);
101
102 mConn = new TestConnHelper(this,
103 TP_TESTS_TYPE_SIMPLE_CONNECTION,
104 "account", "me@example.com",
105 "protocol", "example",
106 NULL);
107 QCOMPARE(mConn->connect(), true);
108 }
109
init()110 void TestCaptchaAuthentication::init()
111 {
112 initImpl();
113 }
114
testCreation()115 void TestCaptchaAuthentication::testCreation()
116 {
117 createCaptchaChannel();
118
119 QCOMPARE(mCaptcha->status(), Tp::CaptchaStatusLocalPending);
120 QCOMPARE(mCaptcha->canRetry(), false);
121 QVERIFY(mCaptcha->error().isEmpty());
122 QVERIFY(mCaptcha->errorDetails().allDetails().isEmpty());
123 }
124
testCaptchaSuccessful()125 void TestCaptchaAuthentication::testCaptchaSuccessful()
126 {
127 createCaptchaChannel();
128
129 QSignalSpy spy(mCaptcha.data(), SIGNAL(statusChanged(Tp::CaptchaStatus)));
130
131 PendingCaptchas *pendingCaptchas = mCaptcha->requestCaptchas(QStringList() << QLatin1String("image/png"));
132 QVERIFY(connect(pendingCaptchas,
133 SIGNAL(finished(Tp::PendingOperation *)),
134 SLOT(expectSuccessfulCall(Tp::PendingOperation *))));
135 QCOMPARE(mLoop->exec(), 0);
136
137 QCOMPARE(pendingCaptchas->requiresMultipleCaptchas(), false);
138 QCOMPARE(pendingCaptchas->captchaList().size(), 1);
139
140 Captcha captchaData = pendingCaptchas->captcha();
141
142 QCOMPARE(captchaData.mimeType(), QLatin1String("image/png"));
143 QCOMPARE(captchaData.label(), QLatin1String("Enter the text displayed"));
144 QCOMPARE(captchaData.data(), QByteArray("This is a fake payload"));
145 QCOMPARE(captchaData.type(), CaptchaAuthentication::OCRChallenge);
146 QCOMPARE(captchaData.id(), (uint)42);
147
148 QVERIFY(connect(mCaptcha->answer(42, QLatin1String("This is the right answer")),
149 SIGNAL(finished(Tp::PendingOperation *)),
150 SLOT(expectSuccessfulCall(Tp::PendingOperation *))));
151 QCOMPARE(mLoop->exec(), 0);
152
153 QCOMPARE(spy.size(), 2);
154 QCOMPARE(mCaptcha->status(), CaptchaStatusSucceeded);
155 }
156
testCaptchaRetry()157 void TestCaptchaAuthentication::testCaptchaRetry()
158 {
159 createCaptchaChannel(true);
160 QSignalSpy spy(mCaptcha.data(), SIGNAL(statusChanged(Tp::CaptchaStatus)));
161
162 PendingCaptchas *pendingCaptchas = mCaptcha->requestCaptchas(QStringList() << QLatin1String("image/png"));
163 QVERIFY(connect(pendingCaptchas,
164 SIGNAL(finished(Tp::PendingOperation *)),
165 SLOT(expectSuccessfulCall(Tp::PendingOperation *))));
166 QCOMPARE(mLoop->exec(), 0);
167
168 QVERIFY(connect(mCaptcha->answer(42, QLatin1String("What is this I don't even")),
169 SIGNAL(finished(Tp::PendingOperation *)),
170 SLOT(expectFailure(Tp::PendingOperation *))));
171 QCOMPARE(mLoop->exec(), 0);
172
173 QCOMPARE(mCaptcha->status(), CaptchaStatusTryAgain);
174
175 pendingCaptchas = mCaptcha->requestCaptchas(QStringList() << QLatin1String("image/png"));
176 QVERIFY(connect(pendingCaptchas,
177 SIGNAL(finished(Tp::PendingOperation *)),
178 SLOT(expectSuccessfulCall(Tp::PendingOperation *))));
179 QCOMPARE(mLoop->exec(), 0);
180
181 QCOMPARE(pendingCaptchas->requiresMultipleCaptchas(), false);
182 QCOMPARE(pendingCaptchas->captchaList().size(), 1);
183
184 Captcha captchaData = pendingCaptchas->captcha();
185
186 QCOMPARE(captchaData.mimeType(), QLatin1String("image/png"));
187 QCOMPARE(captchaData.label(), QLatin1String("Enter the text displayed"));
188 QCOMPARE(captchaData.data(), QByteArray("This is a reloaded payload"));
189 QCOMPARE(captchaData.type(), CaptchaAuthentication::OCRChallenge);
190 QCOMPARE(captchaData.id(), (uint)42);
191
192 QVERIFY(connect(mCaptcha->answer(42, QLatin1String("This is the right answer")),
193 SIGNAL(finished(Tp::PendingOperation *)),
194 SLOT(expectSuccessfulCall(Tp::PendingOperation *))));
195 QCOMPARE(mLoop->exec(), 0);
196
197 QCOMPARE(mCaptcha->status(), CaptchaStatusSucceeded);
198
199 // Check signals now
200 QCOMPARE(spy.size(), 5);
201 }
202
testCaptchaCancel()203 void TestCaptchaAuthentication::testCaptchaCancel()
204 {
205 createCaptchaChannel();
206
207 PendingCaptchas *pendingCaptchas = mCaptcha->requestCaptchas(QStringList() << QLatin1String("image/png"));
208 QVERIFY(connect(pendingCaptchas,
209 SIGNAL(finished(Tp::PendingOperation *)),
210 SLOT(expectSuccessfulCall(Tp::PendingOperation *))));
211 // Check that the result is not still available
212 QCOMPARE(pendingCaptchas->captchaList().size(), 0);
213 QCOMPARE(pendingCaptchas->captcha().id(), (uint)0);
214 QCOMPARE(mLoop->exec(), 0);
215
216 // Cancel now
217 QVERIFY(connect(mCaptcha->cancel(CaptchaCancelReasonUserCancelled),
218 SIGNAL(finished(Tp::PendingOperation *)),
219 SLOT(expectSuccessfulCall(Tp::PendingOperation *))));
220 QCOMPARE(mLoop->exec(), 0);
221
222 QCOMPARE(mCaptcha->status(), CaptchaStatusFailed);
223
224 // Now try performing random actions which should fail
225 QVERIFY(connect(mCaptcha->answer(42, QLatin1String("This is the right answer")),
226 SIGNAL(finished(Tp::PendingOperation *)),
227 SLOT(expectFailure(Tp::PendingOperation *))));
228 QCOMPARE(mLoop->exec(), 0);
229
230 QVERIFY(connect(mCaptcha->answer(CaptchaAnswers()),
231 SIGNAL(finished(Tp::PendingOperation *)),
232 SLOT(expectFailure(Tp::PendingOperation *))));
233 QCOMPARE(mLoop->exec(), 0);
234
235 QVERIFY(connect(mCaptcha->requestCaptchas(),
236 SIGNAL(finished(Tp::PendingOperation *)),
237 SLOT(expectFailure(Tp::PendingOperation *))));
238 QCOMPARE(mLoop->exec(), 0);
239 }
240
testNoCaptcha()241 void TestCaptchaAuthentication::testNoCaptcha()
242 {
243 createCaptchaChannel();
244
245 PendingCaptchas *pendingCaptchas = mCaptcha->requestCaptchas(QStringList(), CaptchaAuthentication::AudioRecognitionChallenge);
246 QVERIFY(connect(pendingCaptchas,
247 SIGNAL(finished(Tp::PendingOperation *)),
248 SLOT(expectFailure(Tp::PendingOperation *))));
249 QCOMPARE(mLoop->exec(), 0);
250
251 pendingCaptchas = mCaptcha->requestCaptchas(QStringList() << QLatin1String("nosuchtype"),
252 CaptchaAuthentication::SpeechRecognitionChallenge | CaptchaAuthentication::SpeechQuestionChallenge);
253 QVERIFY(connect(pendingCaptchas,
254 SIGNAL(finished(Tp::PendingOperation *)),
255 SLOT(expectFailure(Tp::PendingOperation *))));
256 QCOMPARE(mLoop->exec(), 0);
257
258 // Get the qa one
259 pendingCaptchas = mCaptcha->requestCaptchas(QStringList(), CaptchaAuthentication::TextQuestionChallenge);
260 QVERIFY(connect(pendingCaptchas,
261 SIGNAL(finished(Tp::PendingOperation *)),
262 SLOT(expectSuccessfulCall(Tp::PendingOperation *))));
263 QCOMPARE(mLoop->exec(), 0);
264
265 Captcha data = pendingCaptchas->captcha();
266 Captcha data2(pendingCaptchas->captcha());
267
268 QCOMPARE(data.id(), pendingCaptchas->captcha().id());
269 QCOMPARE(data.id(), data2.id());
270
271 // Get the video one to fail utterly
272 pendingCaptchas = mCaptcha->requestCaptchas(QStringList(), CaptchaAuthentication::VideoRecognitionChallenge);
273 QVERIFY(connect(pendingCaptchas,
274 SIGNAL(finished(Tp::PendingOperation *)),
275 SLOT(expectFailure(Tp::PendingOperation *))));
276 QCOMPARE(mLoop->exec(), 0);
277 }
278
cleanup()279 void TestCaptchaAuthentication::cleanup()
280 {
281 cleanupImpl();
282
283 if (mChan && mChan->isValid()) {
284 qDebug() << "waiting for the channel to become invalidated";
285
286 QVERIFY(connect(mChan.data(),
287 SIGNAL(invalidated(Tp::DBusProxy*,QString,QString)),
288 mLoop,
289 SLOT(quit())));
290 tp_base_channel_close(TP_BASE_CHANNEL(mChanService));
291 QCOMPARE(mLoop->exec(), 0);
292 }
293
294 mChan.reset();
295
296 if (mChanService != 0) {
297 g_object_unref(mChanService);
298 mChanService = 0;
299 }
300
301 mLoop->processEvents();
302 }
303
cleanupTestCase()304 void TestCaptchaAuthentication::cleanupTestCase()
305 {
306 QCOMPARE(mConn->disconnect(), true);
307 delete mConn;
308
309 cleanupTestCaseImpl();
310 }
311
312 QTEST_MAIN(TestCaptchaAuthentication)
313 #include "_gen/captcha-authentication.cpp.moc.hpp"
314