/**************************************************************************** ** ** This file is part of the KD Soap project. ** ** SPDX-FileCopyrightText: 2010 Klarälvdalens Datakonsult AB, a KDAB Group company ** ** SPDX-License-Identifier: MIT ** ****************************************************************************/ #include "KDSoapClientInterface.h" #include "KDSoapMessage.h" #include "KDSoapPendingCallWatcher.h" #include "KDSoapValue.h" #include "httpserver_p.h" #include "wsdl_Services.h" #include #include #include using namespace KDSoapUnitTestHelpers; Q_DECLARE_METATYPE(TNS__GetFolderType) class MSExchangeTest : public QObject { Q_OBJECT private Q_SLOTS: void initTestCase() { } void testExchangeMessage() { HttpServerThread server(queryResponse(), HttpServerThread::Public); ExchangeServices service(this); service.setEndPoint(server.endPoint()); TNS__ResolveNamesType req; req.setReturnFullContactData(true); T__NonEmptyArrayOfBaseFolderIdsType folderIds; T__FolderIdType folderId; folderId.setId(QString::fromLatin1("folderId")); QList folderIdList; folderIdList << folderId; folderIds.setFolderId(folderIdList); req.setParentFolderIds(folderIds); T__RequestServerVersion requestServerVersion; requestServerVersion.setVersion(T__ExchangeVersionType(T__ExchangeVersionType::Exchange2007_SP1)); service.setRequestVersionHeader(requestServerVersion); T__ExchangeImpersonationType impersonation; T__ConnectingSIDType sid; sid.setPrincipalName(QString::fromLatin1("dfaure")); sid.setPrimarySmtpAddress(QString::fromLatin1("david.faure@kdab.com")); sid.setSID(QString::fromLatin1("sid")); impersonation.setConnectingSID(sid); service.setImpersonationHeader(impersonation); service.resolveNames(req); // Check what we sent QByteArray expectedRequestXml = QByteArray(xmlEnvBegin11()) + " xmlns:n1=\"http://schemas.microsoft.com/exchange/services/2006/messages\">" "" "" "dfaure" "sid" "david.faure@kdab.com" "" "" "" "" "" "" "" "" "" + xmlEnvEnd() + '\n'; // added by QXmlStreamWriter::writeEndDocument QVERIFY(xmlBufferCompare(server.receivedData(), expectedRequestXml)); } void testNoParentFolderIds() { HttpServerThread server(queryResponse(), HttpServerThread::Public); ExchangeServices service(this); service.setEndPoint(server.endPoint()); TNS__ResolveNamesType req; req.setReturnFullContactData(true); T__NonEmptyStringType unresolvedEntry; unresolvedEntry.setValue("test"); req.setUnresolvedEntry(unresolvedEntry); service.resolveNames(req); // Check what we sent // If this contains , the MS Exchange server will reject it: // The element 'ParentFolderIds' in namespace '.../2006/messages' has incomplete content. QByteArray expectedRequestXml = QByteArray(xmlEnvBegin11()) + ">" "" "" "test" "" "" + xmlEnvEnd() + '\n'; // added by QXmlStreamWriter::writeEndDocument QVERIFY(xmlBufferCompare(server.receivedData(), expectedRequestXml)); } T__TargetFolderIdType targetFolder() { T__TargetFolderIdType folder; T__DistinguishedFolderIdType distinguishedFolder; distinguishedFolder.setId(T__DistinguishedFolderIdNameType::Calendar); T__EmailAddressType mailbox; mailbox.setEmailAddress(QString("Chef@labex.fitformobility.de")); distinguishedFolder.setMailbox(mailbox); folder.setDistinguishedFolderId(distinguishedFolder); return folder; } void testSyncFolder() { HttpServerThread server(queryResponse(), HttpServerThread::Public); ExchangeServices service(this); service.setEndPoint(server.endPoint()); T__TargetFolderIdType folder = targetFolder(); // prepare call TNS__SyncFolderItemsType request; // item shape T__ItemResponseShapeType itemShape; itemShape.setBaseShape(T__DefaultShapeNamesType::Default); request.setItemShape(itemShape); request.setSyncFolderId(folder); // syncstate request.setSyncState("MySyncState"); // max items request.setMaxChangesReturned(10); service.syncFolderItems(request); // Check what we sent QByteArray expectedRequestXml = QByteArray(xmlEnvBegin11()) + ">" "" "" "" "Default" "" "" /* FolderId should not be there because it's a choice... */ "" "" "Chef@labex.fitformobility.de" "" "" "" "MySyncState" "10" "" "" + xmlEnvEnd() + '\n'; // added by QXmlStreamWriter::writeEndDocument QVERIFY(xmlBufferCompare(server.receivedData(), expectedRequestXml)); } void testGetFolder() // SOAP-87 { HttpServerThread server(queryResponse(), HttpServerThread::Public); ExchangeServices service(this); service.setEndPoint(server.endPoint()); TNS__GetFolderType request; // folder shape T__FolderResponseShapeType folderShape; folderShape.setBaseShape(T__DefaultShapeNamesType::IdOnly); T__PathToUnindexedFieldType *pathToUnindexedField = new T__PathToUnindexedFieldType; // ownership will transfer to QSharedPointer pathToUnindexedField->setFieldURI(T__UnindexedFieldURIType::Folder_TotalCount); QList> paths; paths.append(QSharedPointer(pathToUnindexedField)); T__NonEmptyArrayOfPathsToElementType additionalProperties; additionalProperties.setPath(paths); folderShape.setAdditionalProperties(additionalProperties); request.setFolderShape(folderShape); // folder id T__DistinguishedFolderIdType distinguishedFolderId; distinguishedFolderId.setId(T__DistinguishedFolderIdNameType::Calendar); T__EmailAddressType mailbox; mailbox.setEmailAddress(QString("email@nowhere.com")); distinguishedFolderId.setMailbox(mailbox); QList distinguishedFolderIds; distinguishedFolderIds.append(distinguishedFolderId); T__NonEmptyArrayOfBaseFolderIdsType folderIds; folderIds.setDistinguishedFolderId(distinguishedFolderIds); request.setFolderIds(folderIds); // request folder service.getFolder(request); // Check what we sent QByteArray expectedRequestXml = QByteArray(xmlEnvBegin11()) + ">" "" "" "" "IdOnly" "" "" "" "" "" "" "" "email@nowhere.com" "" "" "" "" "" + xmlEnvEnd() + '\n'; // added by QXmlStreamWriter::writeEndDocument QVERIFY(xmlBufferCompare(server.receivedData(), expectedRequestXml)); } void testCreateItem() // SOAP-93 { HttpServerThread server(queryResponse(), HttpServerThread::Public); ExchangeServices service(this); service.setEndPoint(server.endPoint()); TNS__CreateItemType request; T__TargetFolderIdType folder = targetFolder(); request.setSavedItemFolderId(folder); T__NonEmptyArrayOfAllItemsType array; T__CalendarItemType item; item.setSubject("Subject"); array.setCalendarItem(QList() << item); T__MeetingRequestMessageType meetingRequest; T__TimeZoneType meetingTimeZone; meetingTimeZone.setTimeZoneName("W. Europe Standard Time"); meetingRequest.setMeetingTimeZone(meetingTimeZone); array.setMeetingRequest(QList() << meetingRequest); T__AcceptItemType acceptItem; array.setAcceptItem(QList() << acceptItem); request.setItems(array); service.createItem(request); // Check what we sent QByteArray expectedRequestXml = QByteArray(xmlEnvBegin11()) + ">" "" "" "" "" "" "Chef@labex.fitformobility.de" "" "" "" "" "" "Subject" "" "" "" "" "" "" "" "" + xmlEnvEnd() + '\n'; // added by QXmlStreamWriter::writeEndDocument QVERIFY(xmlBufferCompare(server.receivedData(), expectedRequestXml)); } void testUpdateItem() // SOAP-97 { HttpServerThread server(queryResponse(), HttpServerThread::Public); ExchangeServices service(this); service.setEndPoint(server.endPoint()); TNS__UpdateItemType request; T__TargetFolderIdType folder = targetFolder(); request.setSavedItemFolderId(folder); T__ItemChangeType itemChange; T__SetItemFieldType setItemField; T__PathToUnindexedFieldType path; path.setFieldURI(T__UnindexedFieldURIType::Item_Subject); setItemField.setPath(path); T__CalendarItemType calendarItem; calendarItem.setSubject("newSubject"); setItemField.setCalendarItem(calendarItem); T__NonEmptyArrayOfItemChangeDescriptionsType updates; updates.setSetItemField(QList() << setItemField); itemChange.setUpdates(updates); T__NonEmptyArrayOfItemChangesType array; array.setItemChange(QList() << itemChange); request.setItemChanges(array); service.updateItem(request); // Check what we sent QByteArray expectedRequestXml = QByteArray(xmlEnvBegin11()) + ">" "" "" "" "" "" "Chef@labex.fitformobility.de" "" "" "" "" "" "" "" "" "" "newSubject" "" "" "" "" "" "" "" + xmlEnvEnd() + '\n'; // added by QXmlStreamWriter::writeEndDocument QVERIFY(xmlBufferCompare(server.receivedData(), expectedRequestXml)); } void testServerVersionInfo() // SOAP-116 { QByteArray serverResponseXml = "" "" "" "" "" "" "" "" "NoError" "" "H4sIAAAAAAAEAGNgYGcAAotqE0tHE2NTA0ddZ3NHC10TR2djXSdnJ2ddNyMnC2cnczdLU1OD2vBgveDKvOTgksSSVOfEvMSiSgYr0nW65eekpBZ5pjBYkq43LLWoODM/" "j8GaaK3+" "QMuKS4JSk1Mzy1JTQjJzU0nwrU9icYlnXnFJYl5yqncqKb71zS9K9SxJzS32zwtOLSpLLSLByXDfhgNxUW5iUTYklrgYGISA0tDwAxkOUskgCJQyAGI9kJqwW2wmEwW3eq1Q4DWO" "NF+xh5HBY/" "WkZAUxe7elE6ZFHb2QsgSoiL2ukIGBkYGPgRmkhZtBPOh3mQjTJQ8GIaAoLxADratiZGDwdQzw9HX0AylicDN1CwMrRwOtQFyBxP8LxNZY1FkAzTND4h9pWa2bq7XWtWXCjw3TL5" "y/CDI7COiqq+d0AhjuhbDvVqvn8J2s/69qrtKPvWxgLYwMdy6UycUyyHnvb5dd9O3xSrMgqLh5t+3sbxhGwmQZGICGMtw+bWlxXmWD/" "4wd29SnTd+1HC671ef0M4xQQuidI7AMw2RWoPjFOU4CjYymTnZznTzmBzDcTfxyXjSuyadr1dFH2h2bvrMx7FiaXtJGwFG4PGr7krEBANRZ2yGcAwAA" "true" "" "" "" "" "Freedom" "Normal" "14070" "2014-10-02T13:24:47Z" "2014-10-02T13:24:49Z" "false" "" "" "Simon Hain" "Simon.Hain@isec7.com" "SMTP" "" "" "true" "" "" "" "" "" "" "" ""; HttpServerThread server(serverResponseXml, HttpServerThread::Public); ExchangeServices service(this); service.setEndPoint(server.endPoint()); GetFolderJob *job = new GetFolderJob(&service); TNS__GetFolderType request; T__FolderResponseShapeType folderShape; folderShape.setBaseShape(T__DefaultShapeNamesType::IdOnly); request.setFolderShape(folderShape); T__NonEmptyArrayOfBaseFolderIdsType folderIds; QList distinguishedFolderIds; T__DistinguishedFolderIdType distinguishedFolder; distinguishedFolder.setId(T__DistinguishedFolderIdNameType::Inbox); distinguishedFolderIds.append(distinguishedFolder); folderIds.setDistinguishedFolderId(distinguishedFolderIds); request.setFolderIds(folderIds); QEventLoop loop; QObject::connect(job, &GetFolderJob::finished, &loop, &QEventLoop::quit); job->setRequest(request); job->start(); loop.exec(); // comparing with "serverVersion().majorVersion(), 15); QCOMPARE(job->serverVersion().majorBuildNumber(), 995); QCOMPARE(job->serverVersion().minorVersion(), 0); QCOMPARE(job->serverVersion().minorBuildNumber(), 28); QCOMPARE(job->serverVersion().version(), QString("V2_15")); } void testCharactersSequenceValidOrInvalid_data() // We use a token within to later replace by a valid or invalid characters { const QString serverResponseXML = "" "" "" "" "" "" "" "" "NoError" "" "H4sIAAAAAAAEAGNgYGcAAotqE0tHE2NTA0ddZ3NHC10TR2djXSdnJ2ddNyMnC2cnczdLU1OD2vBgveDKvOTgksSSVOfEvMSiSgYr0nW65eekpBZ5pjBYkq43LLWoODM/" "j8GaaK3+" "QMuKS4JSk1Mzy1JTQjJzU0nwrU9icYlnXnFJYl5yqncqKb71zS9K9SxJzS32zwtOLSpLLSLByXDfhgNxUW5iUTYklrgYGISA0tDwAxkOUskgCJQyAGI9kJqwW2wmEwW3eq1Q4DWO" "NF+xh5HBY/" "WkZAUxe7elE6ZFHb2QsgSoiL2ukIGBkYGPgRmkhZtBPOh3mQjTJQ8GIaAoLxADratiZGDwdQzw9HX0AylicDN1CwMrRwOtQFyBxP8LxNZY1FkAzTND4h9pWa2bq7XWtWXCjw3TL5" "y/CDI7COiqq+d0AhjuhbDvVqvn8J2s/69qrtKPvWxgLYwMdy6UycUyyHnvb5dd9O3xSrMgqLh5t+3sbxhGwmQZGICGMtw+bWlxXmWD/" "4wd29SnTd+1HC671ef0M4xQQuidI7AMw2RWoPjFOU4CjYymTnZznTzmBzDcTfxyXjSuyadr1dFH2h2bvrMx7FiaXtJGwFG4PGr7krEBANRZ2yGcAwAA" "true" "" "" "" "" "subject %1" "Normal" "14070" "2014-10-02T13:24:47Z" "2014-10-02T13:24:49Z" "false" "" "" "Simon Hain" "Simon.Hain@isec7.com" "SMTP" "" "" "true" "" "" "" "" "" "" "" ""; TNS__GetFolderType request; T__FolderResponseShapeType folderShape; folderShape.setBaseShape(T__DefaultShapeNamesType::IdOnly); request.setFolderShape(folderShape); T__NonEmptyArrayOfBaseFolderIdsType folderIds; QList distinguishedFolderIds; T__DistinguishedFolderIdType distinguishedFolder; distinguishedFolder.setId(T__DistinguishedFolderIdNameType::Inbox); distinguishedFolderIds.append(distinguishedFolder); folderIds.setDistinguishedFolderId(distinguishedFolderIds); request.setFolderIds(folderIds); QTest::addColumn("serverResponseXml"); QTest::addColumn("request"); QTest::addColumn("expectedResult"); QTest::newRow("invalid 13") << serverResponseXML.arg("") << request << QString("subject ?"); QTest::newRow("valid A") << serverResponseXML.arg("A") << request << QString("subject A"); QTest::newRow("valid B") << serverResponseXML.arg("B") << request << QString("subject B"); QTest::newRow("valid_single_quote") << serverResponseXML.arg("'") << request << QString("subject '"); } void testCharactersSequenceValidOrInvalid() // SOAP-113: invalid XML character within { QFETCH(QString, serverResponseXml); QFETCH(TNS__GetFolderType, request); QFETCH(QString, expectedResult); ; HttpServerThread server(serverResponseXml.toUtf8(), HttpServerThread::Public); ExchangeServices service(this); service.setEndPoint(server.endPoint()); GetFolderJob *job = new GetFolderJob(&service); QEventLoop loop; QObject::connect(job, &GetFolderJob::finished, &loop, &QEventLoop::quit); job->setRequest(request); job->start(); loop.exec(); QVERIFY2(!job->isFault(), qPrintable(job->faultAsString())); TNS__GetFolderResponseType folderResult = job->getFolderResult(); TNS__ArrayOfResponseMessagesType respMessages = folderResult.responseMessages(); QList syncFolderRespList = respMessages.syncFolderItemsResponseMessage(); QCOMPARE(syncFolderRespList.size(), 1); T__SyncFolderItemsChangesType syncFolderChange = syncFolderRespList.first().changes(); QList syncFolderChangeCreate = syncFolderChange.create(); QCOMPARE(syncFolderChangeCreate.size(), 1); T__MessageType message = syncFolderChangeCreate.first().message(); // qDebug() << message.subject(); QCOMPARE(message.itemId().id(), QString("AAMkAGNiY2YxMjY3LTUxYjgtNGI1Yy1hOTM2LTU4MTM5OTZiNjdjYgBGAAAAAABW2gY0kRG1SqggDTNZN6i8BwBIq5JjIBY/" "RqWQllrF0GSkAAAAB35xAADdYfTPFV6CTIqqxeIriLL3ALilZ3SGAAA=")); QCOMPARE(message.subject(), expectedResult); // We are supposed to have replace invalid characters } void testAttachmentMessage() // SOAP-111 { HttpServerThread server(queryResponse(), HttpServerThread::Public); ExchangeServices service(this); service.setEndPoint(server.endPoint()); TNS__CreateAttachmentType request; T__ItemIdType itemId; itemId.setId("id"); itemId.setChangeKey("changeKey"); request.setParentItemId(itemId); T__NonEmptyArrayOfAttachmentsType attachmentsType; QList attachments; T__FileAttachmentType attachment; attachment.setName("fileName"); attachment.setContent(QByteArray("content")); attachments.append(attachment); attachmentsType.setFileAttachment(attachments); request.setAttachments(attachmentsType); service.createAttachment(request); // qDebug() << "received data" << server.receivedData(); // Check what we sent QByteArray expectedRequestXml = QByteArray(xmlEnvBegin11()) + ">" + "" "" "" "" "" "fileName" "Y29udGVudA==" "" "" "" "" + +xmlEnvEnd() + '\n'; // added by QXmlStreamWriter::writeEndDocument QVERIFY(xmlBufferCompare(server.receivedData(), expectedRequestXml)); } void testAttributeGroup() // SOAP-117 { // // [...] // T__FindItemParentType fipt; // has attributes from a AttributeGroup tag fipt.setAbsoluteDenominator(42); fipt.setNumeratorOffset(42); fipt.setIncludesLastItemInRange(true); QCOMPARE(fipt.absoluteDenominator(), 42); QCOMPARE(fipt.numeratorOffset(), 42); QVERIFY(fipt.includesLastItemInRange()); } private: static QByteArray queryResponse() { return QByteArray(xmlEnvBegin11()) + " xmlns:sf=\"urn:sobject.partner.soap.sforce.com\">" "" // TODO "" "" + xmlEnvEnd(); } }; QTEST_MAIN(MSExchangeTest) #include "test_msexchange_wsdl.moc"