1 /*
2  * Copyright (C) 2008-2021 The QXmpp developers
3  *
4  * Authors:
5  *  Melvin Keskin
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 "QXmppClient.h"
26 #include "QXmppVCardIq.h"
27 #include "QXmppVCardManager.h"
28 
29 #include <memory>
30 
31 #include "IntegrationTesting.h"
32 #include "util.h"
33 #include <QObject>
34 
35 Q_DECLARE_METATYPE(QXmppVCardIq);
36 
37 class tst_QXmppVCardManager : public QObject
38 {
39     Q_OBJECT
40 
41 private:
42     Q_SLOT void testHandleStanza_data();
43     Q_SLOT void testHandleStanza();
44 
45     // integration tests
46     Q_SLOT void testSetClientVCard();
47 
48     QXmppClient m_client;
49 };
50 
testHandleStanza_data()51 void tst_QXmppVCardManager::testHandleStanza_data()
52 {
53     QTest::addColumn<QXmppVCardIq>("expectedIq");
54     QTest::addColumn<bool>("isClientVCard");
55 
56 #define ROW(name, iq, clientVCard) \
57     QTest::newRow(QT_STRINGIFY(name)) << iq << clientVCard
58 
59     QXmppVCardIq iq;
60     iq.setType(QXmppIq::Result);
61     iq.setTo("stpeter@jabber.org/roundabout");
62     iq.setFullName("Jeremie Miller");
63 
64     auto iqFromBare = iq;
65     iqFromBare.setFrom("stpeter@jabber.org");
66 
67     auto iqFromFull = iq;
68     iqFromFull.setFrom("stpeter@jabber.org/roundabout");
69 
70     ROW(client-vcard-from-empty, iq, true);
71     ROW(client-vcard-from-bare, iqFromBare, true);
72     ROW(client-vcard-from-full, iqFromFull, false);
73 
74 #undef ROW
75 }
76 
testHandleStanza()77 void tst_QXmppVCardManager::testHandleStanza()
78 {
79     QFETCH(QXmppVCardIq, expectedIq);
80     QFETCH(bool, isClientVCard);
81 
82     // initialize new manager to clear internal values
83     QXmppVCardManager *manager = new QXmppVCardManager();
84     m_client.addExtension(manager);
85 
86     // sets own jid internally
87     m_client.connectToServer("stpeter@jabber.org", {});
88     m_client.disconnectFromServer();
89 
90     bool vCardReceived = false;
91     bool clientVCardReceived = false;
92 
93     QObject context;
94     connect(manager, &QXmppVCardManager::vCardReceived, &context, [&](QXmppVCardIq iq) {
95         vCardReceived = true;
96         QCOMPARE(iq, expectedIq);
97     });
98     connect(manager, &QXmppVCardManager::clientVCardReceived, &context, [&]() {
99         clientVCardReceived = true;
100         QCOMPARE(manager->clientVCard(), expectedIq);
101     });
102 
103     bool accepted = manager->handleStanza(writePacketToDom(expectedIq));
104 
105     QVERIFY(accepted);
106     QVERIFY(vCardReceived);
107     QCOMPARE(clientVCardReceived, isClientVCard);
108 
109     // clean up (client deletes manager)
110     m_client.removeExtension(manager);
111 }
112 
testSetClientVCard()113 void tst_QXmppVCardManager::testSetClientVCard()
114 {
115     SKIP_IF_INTEGRATION_TESTS_DISABLED();
116 
117     auto client = std::make_unique<QXmppClient>();
118     auto *vCardManager = client->findExtension<QXmppVCardManager>();
119     auto config = IntegrationTests::clientConfiguration();
120 
121     QSignalSpy connectSpy(client.get(), &QXmppClient::connected);
122     QSignalSpy disconnectSpy(client.get(), &QXmppClient::disconnected);
123     QSignalSpy vCardSpy(vCardManager, &QXmppVCardManager::clientVCardReceived);
124 
125     // connect to server
126     client->connectToServer(config);
127     QVERIFY2(connectSpy.wait(), "Could not connect to server!");
128 
129     // request own vcard
130     vCardManager->requestClientVCard();
131     QVERIFY(vCardSpy.wait());
132 
133     // check our vcard has the correct address
134     QCOMPARE(vCardManager->clientVCard().from(), client->configuration().jidBare());
135 
136     // set a new vcard
137     QXmppVCardIq newVCard;
138     newVCard.setFirstName(QStringLiteral("Bob"));
139     newVCard.setBirthday(QDate(1, 2, 2000));
140     newVCard.setEmail(QStringLiteral("bob@qxmpp.org"));
141     vCardManager->setClientVCard(newVCard);
142 
143     // there's currently no signal to see whether the change was successful...
144 
145     QCoreApplication::processEvents();
146 
147     // reconnect
148     client->disconnectFromServer();
149     QVERIFY(disconnectSpy.wait());
150 
151     client->connectToServer(config);
152     QVERIFY2(connectSpy.wait(), "Could not connect to server!");
153 
154     // request own vcard
155     vCardManager->requestClientVCard();
156     QVERIFY(vCardSpy.wait());
157 
158     // check our vcard has been changed successfully
159     QCOMPARE(vCardManager->clientVCard().from(), client->configuration().jidBare());
160     QCOMPARE(vCardManager->clientVCard().firstName(), QStringLiteral("Bob"));
161     QCOMPARE(vCardManager->clientVCard().birthday(), QDate(01, 02, 2000));
162     QCOMPARE(vCardManager->clientVCard().email(), QStringLiteral("bob@qxmpp.org"));
163 
164     // reset the vcard for future tests
165     vCardManager->setClientVCard(QXmppVCardIq());
166 
167     // disconnect
168     client->disconnectFromServer();
169     QVERIFY(disconnectSpy.wait());
170 }
171 
172 QTEST_MAIN(tst_QXmppVCardManager)
173 #include "tst_qxmppvcardmanager.moc"
174