// Test parsing of complex replies, like with SugarCRM void testParseComplexReply() { HttpServerThread server(complexTypeResponse(), HttpServerThread::Public); KDSoapClientInterface client(server.endPoint(), countryMessageNamespace()); const KDSoapMessage response = client.call(QLatin1String("getEmployeeCountry"), countryMessage()); QVERIFY(!response.isFault()); QCOMPARE(response.arguments().count(), 1); const KDSoapValueList lst = response.arguments().first().childValues(); QCOMPARE(lst.count(), 3); const KDSoapValue id = lst.first(); QCOMPARE(id.name(), QString::fromLatin1("id")); QCOMPARE(id.value().toString(), QString::fromLatin1("12345")); const KDSoapValue error = lst.at(1); QCOMPARE(error.name(), QString::fromLatin1("error")); const KDSoapValueList errorList = error.childValues(); QCOMPARE(errorList.count(), 3); const KDSoapValue number = errorList.at(0); QCOMPARE(number.name(), QString::fromLatin1("number")); QCOMPARE(number.value().toString(), QString::fromLatin1("0")); const KDSoapValue name = errorList.at(1); QCOMPARE(name.name(), QString::fromLatin1("name")); QCOMPARE(name.value().toString(), QString::fromLatin1("No Error")); const KDSoapValue description = errorList.at(2); QCOMPARE(description.name(), QString::fromLatin1("description")); QCOMPARE(description.value().toString(), QString::fromLatin1("No Error")); const KDSoapValue array = lst.at(2); QCOMPARE(array.name(), QString::fromLatin1("testArray")); //qDebug() << array; // Code from documentation const QString sessionId = response.arguments()[0].value().toString(); Q_UNUSED(sessionId); }
void testCorrectHttpHeader() { HttpServerThread server(countryResponse(), HttpServerThread::Public); KDSoapClientInterface client(server.endPoint(), countryMessageNamespace()); KDSoapAuthentication auth; auth.setUser(QLatin1String("kdab")); auth.setPassword(QLatin1String("unused")); client.setAuthentication(auth); // unused... QNetworkCookieJar myJar; QList<QNetworkCookie> myCookies; myCookies.append(QNetworkCookie("biscuits", "are good")); myJar.setCookiesFromUrl(myCookies, QUrl(server.endPoint())); client.setCookieJar(&myJar); QByteArray expectedRequestXml = expectedCountryRequest(); client.setSoapVersion(KDSoapClientInterface::SOAP1_1); { KDSoapMessage ret = client.call(QLatin1String("getEmployeeCountry"), countryMessage()); // Check what we sent QVERIFY(xmlBufferCompare(server.receivedData(), expectedRequestXml)); QVERIFY(!ret.isFault()); QCOMPARE(server.header("Content-Type").constData(), "text/xml;charset=utf-8"); QCOMPARE(server.header("SoapAction").constData(), "\"http://www.kdab.com/xml/MyWsdl/getEmployeeCountry\""); #if QT_VERSION >= 0x040800 QCOMPARE(server.header("Cookie").constData(), "biscuits=are good"); #elif QT_VERSION >= 0x040700 QCOMPARE(server.header("Cookie").constData(), "biscuits=\"are good\""); #endif QCOMPARE(ret.arguments().child(QLatin1String("employeeCountry")).value().toString(), QString::fromLatin1("France")); } client.setSoapVersion(KDSoapClientInterface::SOAP1_2); { KDSoapMessage ret = client.call(QLatin1String("getEmployeeCountry"), countryMessage()); // Check what we sent QByteArray expectedRequestXml12 = expectedRequestXml; expectedRequestXml12.replace("http://schemas.xmlsoap.org/soap/envelope/", "http://www.w3.org/2003/05/soap-envelope"); expectedRequestXml12.replace("http://schemas.xmlsoap.org/soap/encoding/", "http://www.w3.org/2003/05/soap-encoding"); QVERIFY(xmlBufferCompare(server.receivedData(), expectedRequestXml12)); QVERIFY(!ret.isFault()); QCOMPARE(server.header("Content-Type").constData(), "application/soap+xml;charset=utf-8;action=http://www.kdab.com/xml/MyWsdl/getEmployeeCountry"); QCOMPARE(ret.arguments().child(QLatin1String("employeeCountry")).value().toString(), QString::fromLatin1("France")); #if QT_VERSION >= 0x040800 QCOMPARE(server.header("Cookie").constData(), "biscuits=are good"); #elif QT_VERSION >= 0x040700 QCOMPARE(server.header("Cookie").constData(), "biscuits=\"are good\""); #endif } }
void testDocumentStyle() { HttpServerThread server(countryResponse(), HttpServerThread::Public); KDSoapClientInterface client(server.endPoint(), countryMessageNamespace()); client.setStyle(KDSoapClientInterface::DocumentStyle); QByteArray expectedRequestXml = expectedCountryRequest(); KDSoapMessage message; message = KDSoapValue(QLatin1String("getEmployeeCountry"), QVariant()); KDSoapValueList& args = message.childValues(); args.append(KDSoapValue(QLatin1String("employeeName"), QString::fromUtf8("David Ä Faure"))); { KDSoapMessage ret = client.call(QLatin1String("UNUSED"), message); // Check what we sent QVERIFY(xmlBufferCompare(server.receivedData(), expectedRequestXml)); QVERIFY(!ret.isFault()); QCOMPARE(ret.arguments().child(QLatin1String("employeeCountry")).value().toString(), QString::fromLatin1("France")); } }
// Using direct call(), check the xml we send, the response parsing. // Then test callNoReply, then various ways to use asyncCall. void testCallNoReply() { HttpServerThread server(countryResponse(), HttpServerThread::Public); // First, make the proper call KDSoapClientInterface client(server.endPoint(), countryMessageNamespace()); KDSoapAuthentication auth; auth.setUser(QLatin1String("kdab")); auth.setPassword(QLatin1String("unused")); client.setAuthentication(auth); // unused... QByteArray expectedRequestXml = expectedCountryRequest(); { KDSoapMessage ret = client.call(QLatin1String("getEmployeeCountry"), countryMessage()); // Check what we sent QVERIFY(xmlBufferCompare(server.receivedData(), expectedRequestXml)); QVERIFY(!ret.isFault()); QCOMPARE(ret.arguments().child(QLatin1String("employeeCountry")).value().toString(), QString::fromLatin1("France")); } // Now make the call again, but async, and don't wait for response. server.resetReceivedBuffers(); //qDebug() << "== now calling callNoReply =="; client.callNoReply(QLatin1String("getEmployeeCountry"), countryMessage()); QTest::qWait(200); QVERIFY(xmlBufferCompare(server.receivedData(), expectedRequestXml)); // What happens if we use asyncCall and discard the result? // The KDSoapPendingCall goes out of scope, and the network request is aborted. // // The whole reason KDSoapPendingCall is a value, is so that people don't forget // to delete it. But of course if they even forget to store it, nothing happens. server.resetReceivedBuffers(); { client.asyncCall(QLatin1String("getEmployeeCountry"), countryMessage()); QTest::qWait(200); } QVERIFY(server.receivedData().isEmpty()); }
int main(int argc, char **argv) { QCoreApplication app(argc, argv); const int year = 2009; const QString endPoint = QLatin1String("http://www.holidaywebservice.com/Holidays/US/Dates/USHolidayDates.asmx"); const QString messageNamespace = QLatin1String("http://www.27seconds.com/Holidays/US/Dates/"); KDSoapClientInterface client(endPoint, messageNamespace); KDSoapMessage message; message.setQualified(true); message.addArgument(QLatin1String("year"), year); qDebug("Looking up the date of Valentine's Day in %i...", year); KDSoapMessage response = client.call(QLatin1String("GetValentinesDay"), message); if (response.isFault()) printf("%s\n", qPrintable(response.faultAsString())); else printf("%s\n", qPrintable(response.arguments()[0].value().toString())); return 0; }
void testRequestXml() // this tests the serialization of KDSoapValue[List] in KDSoapClientInterface { HttpServerThread server(emptyResponse(), HttpServerThread::Public); KDSoapClientInterface client(server.endPoint(), countryMessageNamespace()); KDSoapMessage message; message.setUse(KDSoapMessage::EncodedUse); // write out types explicitely // Test simpletype element message.addArgument(QString::fromLatin1("testString"), QString::fromUtf8("Hello Klarälvdalens")); // Test simpletype extended to have an attribute KDSoapValue val(QString::fromLatin1("val"), 5, countryMessageNamespace(), QString::fromLatin1("MyVal")); val.childValues().attributes().append(KDSoapValue(QString::fromLatin1("attr"), QString::fromLatin1("attrValue"))); message.arguments().append(val); // Test complextype with child elements and attributes KDSoapValueList valueList; KDSoapValue orderperson(QString::fromLatin1("orderperson"), QString::fromLatin1("someone"), countryMessageNamespace(), QString::fromLatin1("Person")); valueList.append(orderperson); valueList.attributes().append(KDSoapValue(QString::fromLatin1("attr"), QString::fromLatin1("attrValue"))); message.addArgument(QString::fromLatin1("order"), valueList, countryMessageNamespace(), QString::fromLatin1("MyOrder")); // Code from documentation QRect rect(0, 0, 100, 200); KDSoapValueList rectArgument; rectArgument.addArgument(QLatin1String("x"), rect.x()); rectArgument.addArgument(QLatin1String("y"), rect.y()); rectArgument.addArgument(QLatin1String("width"), rect.width()); rectArgument.addArgument(QLatin1String("height"), rect.height()); message.addArgument(QLatin1String("rect"), rectArgument); // NOTE: type information is missing; setQualified() is missing too. const QString XMLSchemaNS = KDSoapNamespaceManager::xmlSchema2001(); // Test array KDSoapValueList arrayContents; arrayContents.setArrayType(XMLSchemaNS, QString::fromLatin1("string")); arrayContents.append(KDSoapValue(QString::fromLatin1("item"), QString::fromLatin1("kdab"), XMLSchemaNS, QString::fromLatin1("string"))); arrayContents.append(KDSoapValue(QString::fromLatin1("item"), QString::fromLatin1("rocks"), XMLSchemaNS, QString::fromLatin1("string"))); message.addArgument(QString::fromLatin1("testArray"), arrayContents, QString::fromLatin1("http://schemas.xmlsoap.org/soap/encoding/"), QString::fromLatin1("Array")); // Add a header KDSoapMessage header1; header1.setUse(KDSoapMessage::EncodedUse); header1.addArgument(QString::fromLatin1("header1"), QString::fromLatin1("headerValue")); KDSoapHeaders headers; headers << header1; client.call(QLatin1String("test"), message, QString::fromLatin1("MySoapAction"), headers); // Check what we sent QByteArray expectedRequestXml = QByteArray(xmlEnvBegin11()) + " xmlns:n1=\"http://www.kdab.com/xml/MyWsdl/\"" "><soap:Header>" "<n1:header1 xsi:type=\"xsd:string\">headerValue</n1:header1>" "</soap:Header>"; const QByteArray expectedRequestBody = QByteArray("<soap:Body>" "<n1:test>" "<testString xsi:type=\"xsd:string\">Hello Klarälvdalens</testString>" "<val xsi:type=\"n1:MyVal\" attr=\"attrValue\">5</val>" "<order xsi:type=\"n1:MyOrder\" attr=\"attrValue\"><orderperson xsi:type=\"n1:Person\">someone</orderperson></order>" "<rect><x xsi:type=\"xsd:int\">0</x><y xsi:type=\"xsd:int\">0</y><width xsi:type=\"xsd:int\">100</width><height xsi:type=\"xsd:int\">200</height></rect>" "<testArray xsi:type=\"soap-enc:Array\" soap-enc:arrayType=\"xsd:string[2]\">" "<item xsi:type=\"xsd:string\">kdab</item>" "<item xsi:type=\"xsd:string\">rocks</item>" "</testArray>" "</n1:test>" "</soap:Body>") + xmlEnvEnd() + '\n'; // added by QXmlStreamWriter::writeEndDocument QVERIFY(xmlBufferCompare(server.receivedData(), expectedRequestXml + expectedRequestBody)); // Now using persistent headers server.resetReceivedBuffers(); client.setHeader(QLatin1String("header1"), header1); client.call(QLatin1String("test"), message, QString::fromLatin1("MySoapAction")); QVERIFY(xmlBufferCompare(server.receivedData(), expectedRequestXml + expectedRequestBody)); // Now remove the persistent header (using setHeader + empty message) server.resetReceivedBuffers(); client.setHeader(QLatin1String("header1"), KDSoapMessage()); client.call(QLatin1String("test"), message, QString::fromLatin1("MySoapAction")); const QByteArray expectedRequestXmlNoHeader = QByteArray(xmlEnvBegin11()) + " xmlns:n1=\"http://www.kdab.com/xml/MyWsdl/\"" "><soap:Header/>"; // the empty element does not matter QVERIFY(xmlBufferCompare(server.receivedData(), expectedRequestXmlNoHeader + expectedRequestBody)); }