1 /*
2 * Copyright (C) 2008-2021 The QXmpp developers
3 *
4 * Author:
5 * Jeremy Lainé
6 * Linus Jahn
7 *
8 * Source:
9 * https://github.com/qxmpp-project/qxmpp
10 *
11 * This file is a part of QXmpp library.
12 *
13 * This library is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU Lesser General Public
15 * License as published by the Free Software Foundation; either
16 * version 2.1 of the License, or (at your option) any later version.
17 *
18 * This library is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * Lesser General Public License for more details.
22 *
23 */
24
25 #include "QXmppBitsOfBinaryContentId.h"
26 #include "QXmppBitsOfBinaryData.h"
27 #include "QXmppBitsOfBinaryDataList.h"
28 #include "QXmppRegisterIq.h"
29
30 #include "util.h"
31 #include <QObject>
32
33 class tst_QXmppRegisterIq : public QObject
34 {
35 Q_OBJECT
36
37 private slots:
38 void testGet();
39 void testResult();
40 void testResultWithForm();
41 void testSet();
42 void testSetWithForm();
43 void testBobData();
44 void testRegistered();
45 void testRemove();
46 void testChangePassword();
47 void testUnregistration();
48 };
49
testGet()50 void tst_QXmppRegisterIq::testGet()
51 {
52 const QByteArray xml(
53 "<iq id=\"reg1\" to=\"shakespeare.lit\" type=\"get\">"
54 "<query xmlns=\"jabber:iq:register\"/>"
55 "</iq>");
56
57 QXmppRegisterIq iq;
58 parsePacket(iq, xml);
59 QCOMPARE(iq.id(), QLatin1String("reg1"));
60 QCOMPARE(iq.to(), QLatin1String("shakespeare.lit"));
61 QCOMPARE(iq.from(), QString());
62 QCOMPARE(iq.type(), QXmppIq::Get);
63 QCOMPARE(iq.instructions(), QString());
64 QVERIFY(!iq.isRegistered());
65 QVERIFY(!iq.isRemove());
66 QVERIFY(iq.username().isNull());
67 QVERIFY(iq.password().isNull());
68 QVERIFY(iq.email().isNull());
69 QVERIFY(iq.form().isNull());
70 serializePacket(iq, xml);
71 }
72
testResult()73 void tst_QXmppRegisterIq::testResult()
74 {
75 const QByteArray xml(
76 "<iq id=\"reg1\" type=\"result\">"
77 "<query xmlns=\"jabber:iq:register\">"
78 "<instructions>Choose a username and password for use with this service. Please also provide your email address.</instructions>"
79 "<username/>"
80 "<password/>"
81 "<email/>"
82 "</query>"
83 "</iq>");
84
85 QXmppRegisterIq iq;
86 parsePacket(iq, xml);
87 QCOMPARE(iq.id(), QLatin1String("reg1"));
88 QCOMPARE(iq.to(), QString());
89 QCOMPARE(iq.from(), QString());
90 QCOMPARE(iq.type(), QXmppIq::Result);
91 QCOMPARE(iq.instructions(), QLatin1String("Choose a username and password for use with this service. Please also provide your email address."));
92 QVERIFY(!iq.username().isNull());
93 QVERIFY(iq.username().isEmpty());
94 QVERIFY(!iq.password().isNull());
95 QVERIFY(iq.password().isEmpty());
96 QVERIFY(!iq.email().isNull());
97 QVERIFY(iq.email().isEmpty());
98 QVERIFY(iq.form().isNull());
99 serializePacket(iq, xml);
100 }
101
testResultWithForm()102 void tst_QXmppRegisterIq::testResultWithForm()
103 {
104 const QByteArray xml(
105 "<iq id=\"reg3\" to=\"juliet@capulet.com/balcony\" from=\"contests.shakespeare.lit\" type=\"result\">"
106 "<query xmlns=\"jabber:iq:register\">"
107 "<instructions>Use the enclosed form to register. If your Jabber client does not support Data Forms, visit http://www.shakespeare.lit/contests.php</instructions>"
108 "<x xmlns=\"jabber:x:data\" type=\"form\">"
109 "<title>Contest Registration</title>"
110 "<instructions>"
111 "Please provide the following information"
112 "to sign up for our special contests!"
113 "</instructions>"
114 "<field type=\"hidden\" var=\"FORM_TYPE\">"
115 "<value>jabber:iq:register</value>"
116 "</field>"
117 "<field type=\"text-single\" label=\"Given Name\" var=\"first\">"
118 "<required/>"
119 "</field>"
120 "<field type=\"text-single\" label=\"Family Name\" var=\"last\">"
121 "<required/>"
122 "</field>"
123 "<field type=\"text-single\" label=\"Email Address\" var=\"email\">"
124 "<required/>"
125 "</field>"
126 "<field type=\"list-single\" label=\"Gender\" var=\"x-gender\">"
127 "<option label=\"Male\"><value>M</value></option>"
128 "<option label=\"Female\"><value>F</value></option>"
129 "</field>"
130 "</x>"
131 "</query>"
132 "</iq>");
133
134 QXmppRegisterIq iq;
135 parsePacket(iq, xml);
136 QCOMPARE(iq.id(), QLatin1String("reg3"));
137 QCOMPARE(iq.to(), QLatin1String("juliet@capulet.com/balcony"));
138 QCOMPARE(iq.from(), QLatin1String("contests.shakespeare.lit"));
139 QCOMPARE(iq.type(), QXmppIq::Result);
140 QCOMPARE(iq.instructions(), QLatin1String("Use the enclosed form to register. If your Jabber client does not support Data Forms, visit http://www.shakespeare.lit/contests.php"));
141 QVERIFY(iq.username().isNull());
142 QVERIFY(iq.password().isNull());
143 QVERIFY(iq.email().isNull());
144 QVERIFY(!iq.form().isNull());
145 QCOMPARE(iq.form().title(), QLatin1String("Contest Registration"));
146 serializePacket(iq, xml);
147 }
148
testSet()149 void tst_QXmppRegisterIq::testSet()
150 {
151 const QByteArray xml(
152 "<iq id=\"reg2\" type=\"set\">"
153 "<query xmlns=\"jabber:iq:register\">"
154 "<username>bill</username>"
155 "<password>Calliope</password>"
156 "<email>bard@shakespeare.lit</email>"
157 "</query>"
158 "</iq>");
159
160 QXmppRegisterIq iq;
161 parsePacket(iq, xml);
162 QCOMPARE(iq.id(), QLatin1String("reg2"));
163 QCOMPARE(iq.to(), QString());
164 QCOMPARE(iq.from(), QString());
165 QCOMPARE(iq.type(), QXmppIq::Set);
166 QCOMPARE(iq.username(), QLatin1String("bill"));
167 QCOMPARE(iq.password(), QLatin1String("Calliope"));
168 QCOMPARE(iq.email(), QLatin1String("bard@shakespeare.lit"));
169 QVERIFY(iq.form().isNull());
170 serializePacket(iq, xml);
171 }
172
testSetWithForm()173 void tst_QXmppRegisterIq::testSetWithForm()
174 {
175 const QByteArray xml(
176 "<iq id=\"reg4\" to=\"contests.shakespeare.lit\" from=\"juliet@capulet.com/balcony\" type=\"set\">"
177 "<query xmlns=\"jabber:iq:register\">"
178 "<x xmlns=\"jabber:x:data\" type=\"submit\">"
179 "<field type=\"hidden\" var=\"FORM_TYPE\">"
180 "<value>jabber:iq:register</value>"
181 "</field>"
182 "<field type=\"text-single\" label=\"Given Name\" var=\"first\">"
183 "<value>Juliet</value>"
184 "</field>"
185 "<field type=\"text-single\" label=\"Family Name\" var=\"last\">"
186 "<value>Capulet</value>"
187 "</field>"
188 "<field type=\"text-single\" label=\"Email Address\" var=\"email\">"
189 "<value>juliet@capulet.com</value>"
190 "</field>"
191 "<field type=\"list-single\" label=\"Gender\" var=\"x-gender\">"
192 "<value>F</value>"
193 "</field>"
194 "</x>"
195 "</query>"
196 "</iq>");
197
198 QXmppRegisterIq iq;
199 parsePacket(iq, xml);
200 QCOMPARE(iq.id(), QLatin1String("reg4"));
201 QCOMPARE(iq.to(), QLatin1String("contests.shakespeare.lit"));
202 QCOMPARE(iq.from(), QLatin1String("juliet@capulet.com/balcony"));
203 QCOMPARE(iq.type(), QXmppIq::Set);
204 QVERIFY(iq.username().isNull());
205 QVERIFY(iq.password().isNull());
206 QVERIFY(iq.email().isNull());
207 QVERIFY(!iq.form().isNull());
208 serializePacket(iq, xml);
209
210 QXmppRegisterIq sIq;
211 sIq.setId(QLatin1String("reg4"));
212 sIq.setTo(QLatin1String("contests.shakespeare.lit"));
213 sIq.setFrom(QLatin1String("juliet@capulet.com/balcony"));
214 sIq.setType(QXmppIq::Set);
215 sIq.setForm(QXmppDataForm(
216 QXmppDataForm::Submit,
217 QList<QXmppDataForm::Field>()
218 << QXmppDataForm::Field(
219 QXmppDataForm::Field::HiddenField,
220 QStringLiteral("FORM_TYPE"),
221 QStringLiteral("jabber:iq:register"))
222 << QXmppDataForm::Field(
223 QXmppDataForm::Field::TextSingleField,
224 QStringLiteral("first"),
225 QStringLiteral("Juliet"),
226 false,
227 QStringLiteral("Given Name"))
228 << QXmppDataForm::Field(
229 QXmppDataForm::Field::TextSingleField,
230 QStringLiteral("last"),
231 QStringLiteral("Capulet"),
232 false,
233 QStringLiteral("Family Name"))
234 << QXmppDataForm::Field(
235 QXmppDataForm::Field::TextSingleField,
236 QStringLiteral("email"),
237 QStringLiteral("juliet@capulet.com"),
238 false,
239 QStringLiteral("Email Address"))
240 << QXmppDataForm::Field(
241 QXmppDataForm::Field::ListSingleField,
242 QStringLiteral("x-gender"),
243 QStringLiteral("F"),
244 false,
245 QStringLiteral("Gender"))));
246 serializePacket(sIq, xml);
247 }
248
testBobData()249 void tst_QXmppRegisterIq::testBobData()
250 {
251 const QByteArray xml = QByteArrayLiteral(
252 "<iq type=\"result\">"
253 "<query xmlns=\"jabber:iq:register\">"
254 "<data xmlns=\"urn:xmpp:bob\" "
255 "cid=\"sha1+5a4c38d44fc64805cbb2d92d8b208be13ff40c0f@bob.xmpp.org\" "
256 "type=\"image/png\">"
257 "iVBORw0KGgoAAAANSUhEUgAAALQAAAA8BAMAAAA9AI20AAAAG1BMVEX///8AAADf39+"
258 "/v79/f39fX1+fn58/Pz8fHx/8ACGJAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADS0lEQV"
259 "RYhe2WS3MSQRCAYTf7OKY1kT0CxsRjHmh5BENIjqEk6pHVhFzdikqO7CGyP9t59Ox2z"
260 "y6UeWBVqugLzM70Nz39mqnV1lIWgBWiYXV0BYfNZ0mvwypds1r62vH/gf76ZL/88Qlc"
261 "41zeAnQrpx5H3z1Npfr5ovmHusa9SpRiNNIOcdrto6PJ5LLfb5bp9zM+VDq/vptxDEa"
262 "a1sql9I3R5KhtfQsA5gNCWYyulV3TyTUDdfL56BvdDl4x7RiybDq9uBgxh1TTPUHDvA"
263 "qNQb+LpT5sWehxJZKKcU2MZ6sDE7PMgW2mdlBGdy6ODe6fJFdMI+us95dNqftDMdwU6"
264 "+MhpuTS9slcy5TFAcwq0Jt6qssJMTQGp4BGURlmSsNoo5oHL4kqc66NdkDO75mIfCxm"
265 "RAlvHxMLdcb7JONavMJbttXXKoMSneYu3OQTlwkUh4mNayi6js55/2VcsZOQfXIYelz"
266 "xLcntEGc3WVCsCORJVCc5r0ajAcq+EO1Q0oPm7n7+X/3jEReGdL6qT7Ml6FCjY+quJC"
267 "r+D01f6BG0SaHG56ZG32DnY2jcEV1+pU0kxTaEwaGcekN7jyu50U/TV4q6YeieyiNTu"
268 "klDKZLukyjKVNwotCUB3B0XO1WjHT3c0DHSO2zACwut8GOiljJIHaJsrlof/fpWNzGM"
269 "os6TgIY0hZNpJshzSi4igOhy3cl4qK+YgnqHkAYcZEgdW6/HyrEK7afoY7RCFzArLl2"
270 "LLDdrdmmHZfROajwIDfWj8yQG+rzwlA3WvdJiMHtjUekiNrp1oCbmyZDEyKROGjFVDr"
271 "PRzlkR9UAfG/OErnPxrop5BwpoEpXQorq2zcGxbnBJndx8Bh0yljGiGv0B4E8+YP3Xp"
272 "2rGydZNy4csW8W2pIvWhvijoujRJ0luXsoymV+8AXvE9HjII72+oReS6OfomHe3xWg/"
273 "f2coSbDa1XZ1CvGMjy1nH9KBl83oPnQKi+vAXKLjCrRvvT2WCMkPmSFbquiVuTH1qjv"
274 "p4j/u7CWyI5/Hn3KAaJJ90eP0Zp1Kjets4WPaElkxheF7cpBESzXuIdLwyFjSub07tB"
275 "6JjxH3DGiu+zwHHimdtFsMvKqG/nBxm2TwbvyU6LWs5RnJX4dSldg3QhDLAAAAAElFT"
276 "kSuQmCC"
277 "</data>"
278 "</query>"
279 "</iq>");
280
281 QXmppBitsOfBinaryData data;
282 data.setCid(QXmppBitsOfBinaryContentId::fromContentId(
283 QStringLiteral("sha1+5a4c38d44fc64805cbb2d92d8b208be13ff40c0f@bob.xmpp.org")));
284 data.setContentType(QMimeDatabase().mimeTypeForName(QStringLiteral("image/png")));
285 data.setData(QByteArray::fromBase64(QByteArrayLiteral(
286 "iVBORw0KGgoAAAANSUhEUgAAALQAAAA8BAMAAAA9AI20AAAAG1BMVEX///8AAADf39+"
287 "/v79/f39fX1+fn58/Pz8fHx/8ACGJAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADS0lEQV"
288 "RYhe2WS3MSQRCAYTf7OKY1kT0CxsRjHmh5BENIjqEk6pHVhFzdikqO7CGyP9t59Ox2z"
289 "y6UeWBVqugLzM70Nz39mqnV1lIWgBWiYXV0BYfNZ0mvwypds1r62vH/gf76ZL/88Qlc"
290 "41zeAnQrpx5H3z1Npfr5ovmHusa9SpRiNNIOcdrto6PJ5LLfb5bp9zM+VDq/vptxDEa"
291 "a1sql9I3R5KhtfQsA5gNCWYyulV3TyTUDdfL56BvdDl4x7RiybDq9uBgxh1TTPUHDvA"
292 "qNQb+LpT5sWehxJZKKcU2MZ6sDE7PMgW2mdlBGdy6ODe6fJFdMI+us95dNqftDMdwU6"
293 "+MhpuTS9slcy5TFAcwq0Jt6qssJMTQGp4BGURlmSsNoo5oHL4kqc66NdkDO75mIfCxm"
294 "RAlvHxMLdcb7JONavMJbttXXKoMSneYu3OQTlwkUh4mNayi6js55/2VcsZOQfXIYelz"
295 "xLcntEGc3WVCsCORJVCc5r0ajAcq+EO1Q0oPm7n7+X/3jEReGdL6qT7Ml6FCjY+quJC"
296 "r+D01f6BG0SaHG56ZG32DnY2jcEV1+pU0kxTaEwaGcekN7jyu50U/TV4q6YeieyiNTu"
297 "klDKZLukyjKVNwotCUB3B0XO1WjHT3c0DHSO2zACwut8GOiljJIHaJsrlof/fpWNzGM"
298 "os6TgIY0hZNpJshzSi4igOhy3cl4qK+YgnqHkAYcZEgdW6/HyrEK7afoY7RCFzArLl2"
299 "LLDdrdmmHZfROajwIDfWj8yQG+rzwlA3WvdJiMHtjUekiNrp1oCbmyZDEyKROGjFVDr"
300 "PRzlkR9UAfG/OErnPxrop5BwpoEpXQorq2zcGxbnBJndx8Bh0yljGiGv0B4E8+YP3Xp"
301 "2rGydZNy4csW8W2pIvWhvijoujRJ0luXsoymV+8AXvE9HjII72+oReS6OfomHe3xWg/"
302 "f2coSbDa1XZ1CvGMjy1nH9KBl83oPnQKi+vAXKLjCrRvvT2WCMkPmSFbquiVuTH1qjv"
303 "p4j/u7CWyI5/Hn3KAaJJ90eP0Zp1Kjets4WPaElkxheF7cpBESzXuIdLwyFjSub07tB"
304 "6JjxH3DGiu+zwHHimdtFsMvKqG/nBxm2TwbvyU6LWs5RnJX4dSldg3QhDLAAAAAElFT"
305 "kSuQmCC")));
306
307 QXmppRegisterIq parsedIq;
308 parsePacket(parsedIq, xml);
309 QCOMPARE(parsedIq.type(), QXmppIq::Result);
310 QCOMPARE(parsedIq.id(), QStringLiteral(""));
311 QCOMPARE(parsedIq.bitsOfBinaryData().size(), 1);
312 QCOMPARE(parsedIq.bitsOfBinaryData().first().cid().algorithm(), data.cid().algorithm());
313 QCOMPARE(parsedIq.bitsOfBinaryData().first().cid().hash(), data.cid().hash());
314 QCOMPARE(parsedIq.bitsOfBinaryData().first().cid(), data.cid());
315 QCOMPARE(parsedIq.bitsOfBinaryData().first().contentType(), data.contentType());
316 QCOMPARE(parsedIq.bitsOfBinaryData().first().maxAge(), data.maxAge());
317 QCOMPARE(parsedIq.bitsOfBinaryData().first().data(), data.data());
318 QCOMPARE(parsedIq.bitsOfBinaryData().first(), data);
319 serializePacket(parsedIq, xml);
320
321 QXmppRegisterIq iq;
322 iq.setType(QXmppIq::Result);
323 iq.setId(QStringLiteral(""));
324 QXmppBitsOfBinaryDataList bobDataList;
325 bobDataList << data;
326 iq.setBitsOfBinaryData(bobDataList);
327 serializePacket(iq, xml);
328
329 QXmppRegisterIq iq2;
330 iq2.setType(QXmppIq::Result);
331 iq2.setId(QStringLiteral(""));
332 iq2.bitsOfBinaryData() << data;
333 serializePacket(iq2, xml);
334
335 // test const getter
336 const QXmppRegisterIq constIq = iq;
337 QCOMPARE(constIq.bitsOfBinaryData(), iq.bitsOfBinaryData());
338 }
339
testRegistered()340 void tst_QXmppRegisterIq::testRegistered()
341 {
342 const QByteArray xml = QByteArrayLiteral(
343 "<iq type=\"result\">"
344 "<query xmlns=\"jabber:iq:register\">"
345 "<registered/>"
346 "<username>juliet</username>"
347 "</query>"
348 "</iq>");
349
350 QXmppRegisterIq iq;
351 parsePacket(iq, xml);
352 QVERIFY(iq.isRegistered());
353 QCOMPARE(iq.username(), QStringLiteral("juliet"));
354 serializePacket(iq, xml);
355
356 iq = QXmppRegisterIq();
357 iq.setId(QStringLiteral(""));
358 iq.setType(QXmppIq::Result);
359 iq.setIsRegistered(true);
360 iq.setUsername(QStringLiteral("juliet"));
361 serializePacket(iq, xml);
362 }
363
testRemove()364 void tst_QXmppRegisterIq::testRemove()
365 {
366 const QByteArray xml = QByteArrayLiteral(
367 "<iq type=\"result\">"
368 "<query xmlns=\"jabber:iq:register\">"
369 "<remove/>"
370 "<username>juliet</username>"
371 "</query>"
372 "</iq>");
373
374 QXmppRegisterIq iq;
375 parsePacket(iq, xml);
376 QVERIFY(iq.isRemove());
377 QCOMPARE(iq.username(), QStringLiteral("juliet"));
378 serializePacket(iq, xml);
379
380 iq = QXmppRegisterIq();
381 iq.setId(QStringLiteral(""));
382 iq.setType(QXmppIq::Result);
383 iq.setIsRemove(true);
384 iq.setUsername(QStringLiteral("juliet"));
385 serializePacket(iq, xml);
386 }
387
testChangePassword()388 void tst_QXmppRegisterIq::testChangePassword()
389 {
390 const QByteArray xml = QByteArrayLiteral(
391 "<iq id=\"changePassword1\" to=\"shakespeare.lit\" type=\"set\">"
392 "<query xmlns=\"jabber:iq:register\">"
393 "<username>bill</username>"
394 "<password>m1cr0$0ft</password>"
395 "</query>"
396 "</iq>");
397
398 auto iq = QXmppRegisterIq::createChangePasswordRequest(
399 QStringLiteral("bill"),
400 QStringLiteral("m1cr0$0ft"),
401 QStringLiteral("shakespeare.lit"));
402 iq.setId(QStringLiteral("changePassword1"));
403 serializePacket(iq, xml);
404 }
405
testUnregistration()406 void tst_QXmppRegisterIq::testUnregistration()
407 {
408 const QByteArray xml = QByteArrayLiteral(
409 "<iq id=\"unreg1\" to=\"shakespeare.lit\" type=\"set\">"
410 "<query xmlns=\"jabber:iq:register\">"
411 "<remove/>"
412 "</query>"
413 "</iq>");
414
415 auto iq = QXmppRegisterIq::createUnregistrationRequest(QStringLiteral("shakespeare.lit"));
416 iq.setId(QStringLiteral("unreg1"));
417 serializePacket(iq, xml);
418 }
419
420 QTEST_MAIN(tst_QXmppRegisterIq)
421 #include "tst_qxmppregisteriq.moc"
422