1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the test suite of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file. Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
43 #include <QDeclarativeEngine>
44 #include <QDeclarativeComponent>
46 #include <QNetworkCookieJar>
47 #include "testhttpserver.h"
48 #include "../../../shared/util.h"
50 #define SERVER_PORT 14445
53 // In Symbian OS test data is located in applications private dir
57 class tst_qdeclarativexmlhttprequest : public QObject
61 tst_qdeclarativexmlhttprequest() {}
64 void domExceptionCodes();
65 void callbackException();
66 void callbackException_data();
67 void staticStateValues();
68 void instanceStateValues();
73 void open_invalid_method();
75 void open_arg_count();
76 void setRequestHeader();
77 void setRequestHeader_unsent();
78 void setRequestHeader_illegalName_data();
79 void setRequestHeader_illegalName();
80 void setRequestHeader_sent();
81 void setRequestHeader_args();
83 void send_alreadySent();
84 void send_ignoreData();
86 void send_withdata_data();
90 void getResponseHeader();
91 void getResponseHeader_unsent();
92 void getResponseHeader_sent();
93 void getResponseHeader_args();
94 void getAllResponseHeaders();
95 void getAllResponseHeaders_unsent();
96 void getAllResponseHeaders_sent();
97 void getAllResponseHeaders_args();
101 void statusText_data();
103 void responseText_data();
104 void responseXML_invalid();
105 void invalidMethodUsage();
118 // void outstanding_request_at_shutdown();
120 // void network_errors()
124 QDeclarativeEngine engine;
127 inline QUrl TEST_FILE(const QString &filename)
129 return QUrl::fromLocalFile(QLatin1String(SRCDIR) + QLatin1String("/data/") + filename);
132 // Test that the dom exception codes are correct
133 void tst_qdeclarativexmlhttprequest::domExceptionCodes()
135 QDeclarativeComponent component(&engine, TEST_FILE("domExceptionCodes.qml"));
136 QObject *object = component.create();
137 QVERIFY(object != 0);
139 QCOMPARE(object->property("index_size_err").toInt(), 1);
140 QCOMPARE(object->property("domstring_size_err").toInt(), 2);
141 QCOMPARE(object->property("hierarchy_request_err").toInt(), 3);
142 QCOMPARE(object->property("wrong_document_err").toInt(), 4);
143 QCOMPARE(object->property("invalid_character_err").toInt(), 5);
144 QCOMPARE(object->property("no_data_allowed_err").toInt(), 6);
145 QCOMPARE(object->property("no_modification_allowed_err").toInt(), 7);
146 QCOMPARE(object->property("not_found_err").toInt(), 8);
147 QCOMPARE(object->property("not_supported_err").toInt(), 9);
148 QCOMPARE(object->property("inuse_attribute_err").toInt(), 10);
149 QCOMPARE(object->property("invalid_state_err").toInt(), 11);
150 QCOMPARE(object->property("syntax_err").toInt(), 12);
151 QCOMPARE(object->property("invalid_modification_err").toInt(), 13);
152 QCOMPARE(object->property("namespace_err").toInt(), 14);
153 QCOMPARE(object->property("invalid_access_err").toInt(), 15);
154 QCOMPARE(object->property("validation_err").toInt(), 16);
155 QCOMPARE(object->property("type_mismatch_err").toInt(), 17);
160 void tst_qdeclarativexmlhttprequest::callbackException_data()
162 QTest::addColumn<QString>("which");
163 QTest::addColumn<int>("line");
165 QTest::newRow("on-opened") << "1" << 15;
166 QTest::newRow("on-loading") << "3" << 15;
167 QTest::newRow("on-done") << "4" << 15;
170 void tst_qdeclarativexmlhttprequest::callbackException()
172 // Test exception reporting for exceptions thrown at various points.
174 QFETCH(QString, which);
177 QString expect = TEST_FILE("callbackException.qml").toString() + ":"+QString::number(line)+": Error: Exception from Callback";
178 QTest::ignoreMessage(QtWarningMsg, expect.toLatin1());
180 QDeclarativeComponent component(&engine, TEST_FILE("callbackException.qml"));
181 QObject *object = component.beginCreate(engine.rootContext());
182 QVERIFY(object != 0);
183 object->setProperty("url", "testdocument.html");
184 object->setProperty("which", which);
185 component.completeCreate();
187 QTRY_VERIFY(object->property("threw").toBool() == true);
192 // Test that the state value properties on the XMLHttpRequest constructor have the correct values.
193 // ### WebKit does not do this, but it seems to fit the standard and QML better
194 void tst_qdeclarativexmlhttprequest::staticStateValues()
196 QDeclarativeComponent component(&engine, TEST_FILE("staticStateValues.qml"));
197 QObject *object = component.create();
198 QVERIFY(object != 0);
200 QCOMPARE(object->property("unsent").toInt(), 0);
201 QCOMPARE(object->property("opened").toInt(), 1);
202 QCOMPARE(object->property("headers_received").toInt(), 2);
203 QCOMPARE(object->property("loading").toInt(), 3);
204 QCOMPARE(object->property("done").toInt(), 4);
209 // Test that the state value properties on instances have the correct values.
210 void tst_qdeclarativexmlhttprequest::instanceStateValues()
212 QDeclarativeComponent component(&engine, TEST_FILE("instanceStateValues.qml"));
213 QObject *object = component.create();
214 QVERIFY(object != 0);
216 QCOMPARE(object->property("unsent").toInt(), 0);
217 QCOMPARE(object->property("opened").toInt(), 1);
218 QCOMPARE(object->property("headers_received").toInt(), 2);
219 QCOMPARE(object->property("loading").toInt(), 3);
220 QCOMPARE(object->property("done").toInt(), 4);
225 // Test calling constructor
226 void tst_qdeclarativexmlhttprequest::constructor()
228 QDeclarativeComponent component(&engine, TEST_FILE("constructor.qml"));
229 QObject *object = component.create();
230 QVERIFY(object != 0);
232 QCOMPARE(object->property("calledAsConstructor").toBool(), true);
233 QCOMPARE(object->property("calledAsFunction").toBool(), true);
238 // Test that all the properties are set correctly before any request is sent
239 void tst_qdeclarativexmlhttprequest::defaultState()
241 QDeclarativeComponent component(&engine, TEST_FILE("defaultState.qml"));
242 QObject *object = component.create();
243 QVERIFY(object != 0);
245 QCOMPARE(object->property("readState").toInt(), 0);
246 QCOMPARE(object->property("statusIsException").toBool(), true);
247 QCOMPARE(object->property("statusTextIsException").toBool(), true);
248 QCOMPARE(object->property("responseText").toString(), QString());
249 QCOMPARE(object->property("responseXMLIsNull").toBool(), true);
254 // Test valid XMLHttpRequest.open() calls
255 void tst_qdeclarativexmlhttprequest::open()
257 QFETCH(QUrl, qmlFile);
258 QFETCH(QString, url);
259 QFETCH(bool, remote);
261 TestHTTPServer *server = 0;
263 server = new TestHTTPServer(SERVER_PORT);
264 QVERIFY(server->isValid());
265 QVERIFY(server->wait(TEST_FILE("open_network.expect"),
266 TEST_FILE("open_network.reply"),
267 TEST_FILE("testdocument.html")));
270 QDeclarativeComponent component(&engine, qmlFile);
271 QObject *object = component.beginCreate(engine.rootContext());
272 QVERIFY(object != 0);
273 object->setProperty("url", url);
274 component.completeCreate();
276 QCOMPARE(object->property("readyState").toBool(), true);
277 QCOMPARE(object->property("openedState").toBool(), true);
278 QCOMPARE(object->property("status").toBool(), true);
279 QCOMPARE(object->property("statusText").toBool(), true);
280 QCOMPARE(object->property("responseText").toBool(), true);
281 QCOMPARE(object->property("responseXML").toBool(), true);
283 QTRY_VERIFY(object->property("dataOK").toBool() == true);
289 void tst_qdeclarativexmlhttprequest::open_data()
291 QTest::addColumn<QUrl>("qmlFile");
292 QTest::addColumn<QString>("url");
293 QTest::addColumn<bool>("remote");
295 QTest::newRow("Relative url)") << TEST_FILE("open.qml") << "testdocument.html" << false;
296 QTest::newRow("Absolute url)") << TEST_FILE("open.qml") << TEST_FILE("testdocument.html").toString() << false;
297 QTest::newRow("Absolute network url)") << TEST_FILE("open.qml") << "http://127.0.0.1:14445/testdocument.html" << true;
299 // ### Check that the username/password were sent to the server
300 QTest::newRow("User/pass") << TEST_FILE("open_user.qml") << "http://127.0.0.1:14445/testdocument.html" << true;
303 // Test that calling XMLHttpRequest.open() with an invalid method raises an exception
304 void tst_qdeclarativexmlhttprequest::open_invalid_method()
306 QDeclarativeComponent component(&engine, TEST_FILE("open_invalid_method.qml"));
307 QObject *object = component.create();
308 QVERIFY(object != 0);
310 QCOMPARE(object->property("exceptionThrown").toBool(), true);
315 // Test that calling XMLHttpRequest.open() with sync raises an exception
316 void tst_qdeclarativexmlhttprequest::open_sync()
318 QDeclarativeComponent component(&engine, TEST_FILE("open_sync.qml"));
319 QObject *object = component.create();
320 QVERIFY(object != 0);
322 QCOMPARE(object->property("exceptionThrown").toBool(), true);
327 // Calling with incorrect arg count raises an exception
328 void tst_qdeclarativexmlhttprequest::open_arg_count()
331 QDeclarativeComponent component(&engine, TEST_FILE("open_arg_count.1.qml"));
332 QObject *object = component.create();
333 QVERIFY(object != 0);
335 QCOMPARE(object->property("exceptionThrown").toBool(), true);
341 QDeclarativeComponent component(&engine, TEST_FILE("open_arg_count.2.qml"));
342 QObject *object = component.create();
343 QVERIFY(object != 0);
345 QCOMPARE(object->property("exceptionThrown").toBool(), true);
351 // Test valid setRequestHeader() calls
352 void tst_qdeclarativexmlhttprequest::setRequestHeader()
354 TestHTTPServer server(SERVER_PORT);
355 QVERIFY(server.isValid());
356 QVERIFY(server.wait(TEST_FILE("setRequestHeader.expect"),
357 TEST_FILE("setRequestHeader.reply"),
358 TEST_FILE("testdocument.html")));
360 QDeclarativeComponent component(&engine, TEST_FILE("setRequestHeader.qml"));
361 QObject *object = component.beginCreate(engine.rootContext());
362 QVERIFY(object != 0);
363 object->setProperty("url", "http://127.0.0.1:14445/testdocument.html");
364 component.completeCreate();
366 QTRY_VERIFY(object->property("dataOK").toBool() == true);
371 // Test setting headers before open() throws exception
372 void tst_qdeclarativexmlhttprequest::setRequestHeader_unsent()
374 QDeclarativeComponent component(&engine, TEST_FILE("setRequestHeader_unsent.qml"));
375 QObject *object = component.create();
376 QVERIFY(object != 0);
378 QCOMPARE(object->property("test").toBool(), true);
383 void tst_qdeclarativexmlhttprequest::setRequestHeader_illegalName_data()
385 QTest::addColumn<QString>("name");
387 QTest::newRow("Accept-Charset") << "AccePT-CHArset";
388 QTest::newRow("Accept-Encoding") << "AccEpt-EnCOding";
389 QTest::newRow("Connection") << "ConnECtion";
390 QTest::newRow("Content-Length") << "ContEnt-LenGth";
391 QTest::newRow("Cookie") << "CookIe";
392 QTest::newRow("Cookie2") << "CoOkie2";
393 QTest::newRow("Content-Transfer-Encoding") << "ConteNT-tRANSFER-eNCOding";
394 QTest::newRow("Date") << "DaTE";
395 QTest::newRow("Expect") << "ExPect";
396 QTest::newRow("Host") << "HoST";
397 QTest::newRow("Keep-Alive") << "KEEP-aLive";
398 QTest::newRow("Referer") << "ReferEr";
399 QTest::newRow("TE") << "Te";
400 QTest::newRow("Trailer") << "TraILEr";
401 QTest::newRow("Transfer-Encoding") << "tRANsfer-Encoding";
402 QTest::newRow("Upgrade") << "UpgrADe";
403 QTest::newRow("User-Agent") << "uSEr-Agent";
404 QTest::newRow("Via") << "vIa";
405 QTest::newRow("Proxy-") << "ProXy-";
406 QTest::newRow("Sec-") << "SeC-";
407 QTest::newRow("Proxy-*") << "Proxy-BLAH";
408 QTest::newRow("Sec-*") << "Sec-F";
411 // Tests that using illegal header names has no effect
412 void tst_qdeclarativexmlhttprequest::setRequestHeader_illegalName()
414 QFETCH(QString, name);
416 TestHTTPServer server(SERVER_PORT);
417 QVERIFY(server.isValid());
418 QVERIFY(server.wait(TEST_FILE("open_network.expect"),
419 TEST_FILE("open_network.reply"),
420 TEST_FILE("testdocument.html")));
422 QDeclarativeComponent component(&engine, TEST_FILE("setRequestHeader_illegalName.qml"));
423 QObject *object = component.beginCreate(engine.rootContext());
424 QVERIFY(object != 0);
425 object->setProperty("url", "http://127.0.0.1:14445/testdocument.html");
426 object->setProperty("header", name);
427 component.completeCreate();
429 QCOMPARE(object->property("readyState").toBool(), true);
430 QCOMPARE(object->property("openedState").toBool(), true);
431 QCOMPARE(object->property("status").toBool(), true);
432 QCOMPARE(object->property("statusText").toBool(), true);
433 QCOMPARE(object->property("responseText").toBool(), true);
434 QCOMPARE(object->property("responseXML").toBool(), true);
436 QTRY_VERIFY(object->property("dataOK").toBool() == true);
441 // Test that attempting to set a header after a request is sent throws an exception
442 void tst_qdeclarativexmlhttprequest::setRequestHeader_sent()
444 TestHTTPServer server(SERVER_PORT);
445 QVERIFY(server.isValid());
446 QVERIFY(server.wait(TEST_FILE("open_network.expect"),
447 TEST_FILE("open_network.reply"),
448 TEST_FILE("testdocument.html")));
450 QDeclarativeComponent component(&engine, TEST_FILE("setRequestHeader_sent.qml"));
451 QObject *object = component.beginCreate(engine.rootContext());
452 QVERIFY(object != 0);
453 object->setProperty("url", "http://127.0.0.1:14445/testdocument.html");
454 component.completeCreate();
456 QCOMPARE(object->property("test").toBool(), true);
458 QTRY_VERIFY(object->property("dataOK").toBool() == true);
463 // Invalid arg count throws exception
464 void tst_qdeclarativexmlhttprequest::setRequestHeader_args()
466 QDeclarativeComponent component(&engine, TEST_FILE("setRequestHeader_args.qml"));
467 QObject *object = component.create();
468 QVERIFY(object != 0);
470 QCOMPARE(object->property("exceptionThrown").toBool(), true);
475 // Test that calling send() in UNSENT state throws an exception
476 void tst_qdeclarativexmlhttprequest::send_unsent()
478 QDeclarativeComponent component(&engine, TEST_FILE("send_unsent.qml"));
479 QObject *object = component.create();
480 QVERIFY(object != 0);
482 QCOMPARE(object->property("test").toBool(), true);
487 // Test attempting to resend a sent request throws an exception
488 void tst_qdeclarativexmlhttprequest::send_alreadySent()
490 QDeclarativeComponent component(&engine, TEST_FILE("send_alreadySent.qml"));
491 QObject *object = component.create();
492 QVERIFY(object != 0);
494 QCOMPARE(object->property("test").toBool(), true);
495 QTRY_VERIFY(object->property("dataOK").toBool() == true);
500 // Test that send for a GET or HEAD ignores data
501 void tst_qdeclarativexmlhttprequest::send_ignoreData()
504 TestHTTPServer server(SERVER_PORT);
505 QVERIFY(server.isValid());
506 QVERIFY(server.wait(TEST_FILE("send_ignoreData_GET.expect"),
507 TEST_FILE("send_ignoreData.reply"),
508 TEST_FILE("testdocument.html")));
510 QDeclarativeComponent component(&engine, TEST_FILE("send_ignoreData.qml"));
511 QObject *object = component.beginCreate(engine.rootContext());
512 QVERIFY(object != 0);
513 object->setProperty("reqType", "GET");
514 object->setProperty("url", "http://127.0.0.1:14445/testdocument.html");
515 component.completeCreate();
517 QTRY_VERIFY(object->property("dataOK").toBool() == true);
523 TestHTTPServer server(SERVER_PORT);
524 QVERIFY(server.isValid());
525 QVERIFY(server.wait(TEST_FILE("send_ignoreData_PUT.expect"),
526 TEST_FILE("send_ignoreData.reply"),
529 QDeclarativeComponent component(&engine, TEST_FILE("send_ignoreData.qml"));
530 QObject *object = component.beginCreate(engine.rootContext());
531 QVERIFY(object != 0);
532 object->setProperty("reqType", "HEAD");
533 object->setProperty("url", "http://127.0.0.1:14445/testdocument.html");
534 component.completeCreate();
536 QTRY_VERIFY(object->property("dataOK").toBool() == true);
542 // Test that send()'ing data works
543 void tst_qdeclarativexmlhttprequest::send_withdata()
545 QFETCH(QString, file_expected);
546 QFETCH(QString, file_qml);
548 TestHTTPServer server(SERVER_PORT);
549 QVERIFY(server.isValid());
550 QVERIFY(server.wait(TEST_FILE(file_expected),
551 TEST_FILE("send_data.reply"),
552 TEST_FILE("testdocument.html")));
554 QDeclarativeComponent component(&engine, TEST_FILE(file_qml));
555 QObject *object = component.beginCreate(engine.rootContext());
556 QVERIFY(object != 0);
557 object->setProperty("url", "http://127.0.0.1:14445/testdocument.html");
558 component.completeCreate();
560 QTRY_VERIFY(object->property("dataOK").toBool() == true);
565 void tst_qdeclarativexmlhttprequest::send_withdata_data()
567 QTest::addColumn<QString>("file_expected");
568 QTest::addColumn<QString>("file_qml");
570 QTest::newRow("No content-type") << "send_data.1.expect" << "send_data.1.qml";
571 QTest::newRow("Correct content-type") << "send_data.1.expect" << "send_data.2.qml";
572 QTest::newRow("Incorrect content-type") << "send_data.1.expect" << "send_data.3.qml";
573 QTest::newRow("Correct content-type - out of order") << "send_data.4.expect" << "send_data.4.qml";
574 QTest::newRow("Incorrect content-type - out of order") << "send_data.4.expect" << "send_data.5.qml";
575 QTest::newRow("PUT") << "send_data.6.expect" << "send_data.6.qml";
576 QTest::newRow("Correct content-type - no charset") << "send_data.1.expect" << "send_data.7.qml";
579 // Test abort() has no effect in unsent state
580 void tst_qdeclarativexmlhttprequest::abort_unsent()
582 QDeclarativeComponent component(&engine, TEST_FILE("abort_unsent.qml"));
583 QObject *object = component.beginCreate(engine.rootContext());
584 QVERIFY(object != 0);
585 object->setProperty("url", "testdocument.html");
586 component.completeCreate();
588 QCOMPARE(object->property("readyState").toBool(), true);
589 QCOMPARE(object->property("openedState").toBool(), true);
590 QCOMPARE(object->property("status").toBool(), true);
591 QCOMPARE(object->property("statusText").toBool(), true);
592 QCOMPARE(object->property("responseText").toBool(), true);
593 QCOMPARE(object->property("responseXML").toBool(), true);
595 QTRY_VERIFY(object->property("dataOK").toBool() == true);
600 // Test abort() cancels an open (but unsent) request
601 void tst_qdeclarativexmlhttprequest::abort_opened()
603 QDeclarativeComponent component(&engine, TEST_FILE("abort_opened.qml"));
604 QObject *object = component.beginCreate(engine.rootContext());
605 QVERIFY(object != 0);
606 object->setProperty("url", "testdocument.html");
607 component.completeCreate();
609 QCOMPARE(object->property("readyState").toBool(), true);
610 QCOMPARE(object->property("openedState").toBool(), true);
611 QCOMPARE(object->property("status").toBool(), true);
612 QCOMPARE(object->property("statusText").toBool(), true);
613 QCOMPARE(object->property("responseText").toBool(), true);
614 QCOMPARE(object->property("responseXML").toBool(), true);
616 QTRY_VERIFY(object->property("dataOK").toBool() == true);
621 // Test abort() aborts in progress send
622 void tst_qdeclarativexmlhttprequest::abort()
624 TestHTTPServer server(SERVER_PORT);
625 QVERIFY(server.isValid());
626 QVERIFY(server.wait(TEST_FILE("abort.expect"),
627 TEST_FILE("abort.reply"),
628 TEST_FILE("testdocument.html")));
630 QDeclarativeComponent component(&engine, TEST_FILE("abort.qml"));
631 QObject *object = component.beginCreate(engine.rootContext());
632 QVERIFY(object != 0);
633 object->setProperty("urlDummy", "http://127.0.0.1:14449/testdocument.html");
634 object->setProperty("url", "http://127.0.0.1:14445/testdocument.html");
635 component.completeCreate();
637 QCOMPARE(object->property("seenDone").toBool(), true);
638 QCOMPARE(object->property("didNotSeeUnsent").toBool(), true);
639 QCOMPARE(object->property("endStateUnsent").toBool(), true);
641 QTRY_VERIFY(object->property("dataOK").toBool() == true);
646 void tst_qdeclarativexmlhttprequest::getResponseHeader()
648 QDeclarativeEngine engine; // Avoid cookie contamination
650 TestHTTPServer server(SERVER_PORT);
651 QVERIFY(server.isValid());
652 QVERIFY(server.wait(TEST_FILE("getResponseHeader.expect"),
653 TEST_FILE("getResponseHeader.reply"),
654 TEST_FILE("testdocument.html")));
657 QDeclarativeComponent component(&engine, TEST_FILE("getResponseHeader.qml"));
658 QObject *object = component.beginCreate(engine.rootContext());
659 QVERIFY(object != 0);
660 object->setProperty("url", "http://127.0.0.1:14445/testdocument.html");
661 component.completeCreate();
663 QCOMPARE(object->property("unsentException").toBool(), true);
664 QCOMPARE(object->property("openedException").toBool(), true);
665 QCOMPARE(object->property("readyState").toBool(), true);
666 QCOMPARE(object->property("openedState").toBool(), true);
668 QTRY_VERIFY(object->property("dataOK").toBool() == true);
670 QCOMPARE(object->property("headersReceivedState").toBool(), true);
671 QCOMPARE(object->property("headersReceivedNullHeader").toBool(), true);
672 QCOMPARE(object->property("headersReceivedValidHeader").toBool(), true);
673 QCOMPARE(object->property("headersReceivedMultiValidHeader").toBool(), true);
674 QCOMPARE(object->property("headersReceivedCookieHeader").toBool(), true);
676 QCOMPARE(object->property("doneState").toBool(), true);
677 QCOMPARE(object->property("doneNullHeader").toBool(), true);
678 QCOMPARE(object->property("doneValidHeader").toBool(), true);
679 QCOMPARE(object->property("doneMultiValidHeader").toBool(), true);
680 QCOMPARE(object->property("doneCookieHeader").toBool(), true);
685 // Test getResponseHeader throws an exception in an invalid state
686 void tst_qdeclarativexmlhttprequest::getResponseHeader_unsent()
688 QDeclarativeComponent component(&engine, TEST_FILE("getResponseHeader_unsent.qml"));
689 QObject *object = component.create();
690 QVERIFY(object != 0);
692 QCOMPARE(object->property("test").toBool(), true);
697 // Test getResponseHeader throws an exception in an invalid state
698 void tst_qdeclarativexmlhttprequest::getResponseHeader_sent()
700 QDeclarativeComponent component(&engine, TEST_FILE("getResponseHeader_sent.qml"));
701 QObject *object = component.create();
702 QVERIFY(object != 0);
704 QCOMPARE(object->property("test").toBool(), true);
709 // Invalid arg count throws exception
710 void tst_qdeclarativexmlhttprequest::getResponseHeader_args()
712 QDeclarativeComponent component(&engine, TEST_FILE("getResponseHeader_args.qml"));
713 QObject *object = component.create();
714 QVERIFY(object != 0);
716 QTRY_VERIFY(object->property("exceptionThrown").toBool() == true);
721 void tst_qdeclarativexmlhttprequest::getAllResponseHeaders()
723 QDeclarativeEngine engine; // Avoid cookie contamination
725 TestHTTPServer server(SERVER_PORT);
726 QVERIFY(server.isValid());
727 QVERIFY(server.wait(TEST_FILE("getResponseHeader.expect"),
728 TEST_FILE("getResponseHeader.reply"),
729 TEST_FILE("testdocument.html")));
731 QDeclarativeComponent component(&engine, TEST_FILE("getAllResponseHeaders.qml"));
732 QObject *object = component.beginCreate(engine.rootContext());
733 QVERIFY(object != 0);
734 object->setProperty("url", "http://127.0.0.1:14445/testdocument.html");
735 component.completeCreate();
737 QCOMPARE(object->property("unsentException").toBool(), true);
738 QCOMPARE(object->property("openedException").toBool(), true);
739 QCOMPARE(object->property("readyState").toBool(), true);
740 QCOMPARE(object->property("openedState").toBool(), true);
742 QTRY_VERIFY(object->property("dataOK").toBool() == true);
744 QCOMPARE(object->property("headersReceivedState").toBool(), true);
745 QCOMPARE(object->property("headersReceivedHeader").toBool(), true);
747 QCOMPARE(object->property("doneState").toBool(), true);
748 QCOMPARE(object->property("doneHeader").toBool(), true);
753 // Test getAllResponseHeaders throws an exception in an invalid state
754 void tst_qdeclarativexmlhttprequest::getAllResponseHeaders_unsent()
756 QDeclarativeComponent component(&engine, TEST_FILE("getAllResponseHeaders_unsent.qml"));
757 QObject *object = component.create();
758 QVERIFY(object != 0);
760 QCOMPARE(object->property("test").toBool(), true);
765 // Test getAllResponseHeaders throws an exception in an invalid state
766 void tst_qdeclarativexmlhttprequest::getAllResponseHeaders_sent()
768 QDeclarativeComponent component(&engine, TEST_FILE("getAllResponseHeaders_sent.qml"));
769 QObject *object = component.create();
770 QVERIFY(object != 0);
772 QCOMPARE(object->property("test").toBool(), true);
777 // Invalid arg count throws exception
778 void tst_qdeclarativexmlhttprequest::getAllResponseHeaders_args()
780 QDeclarativeComponent component(&engine, TEST_FILE("getAllResponseHeaders_args.qml"));
781 QObject *object = component.create();
782 QVERIFY(object != 0);
784 QTRY_VERIFY(object->property("exceptionThrown").toBool() == true);
789 void tst_qdeclarativexmlhttprequest::status()
791 QFETCH(QUrl, replyUrl);
794 TestHTTPServer server(SERVER_PORT);
795 QVERIFY(server.isValid());
796 QVERIFY(server.wait(TEST_FILE("status.expect"),
798 TEST_FILE("testdocument.html")));
800 QDeclarativeComponent component(&engine, TEST_FILE("status.qml"));
801 QObject *object = component.beginCreate(engine.rootContext());
802 QVERIFY(object != 0);
803 object->setProperty("url", "http://127.0.0.1:14445/testdocument.html");
804 object->setProperty("expectedStatus", status);
805 component.completeCreate();
807 QTRY_VERIFY(object->property("dataOK").toBool() == true);
809 QCOMPARE(object->property("unsentException").toBool(), true);
810 QCOMPARE(object->property("openedException").toBool(), true);
811 QCOMPARE(object->property("sentException").toBool(), true);
812 QCOMPARE(object->property("headersReceived").toBool(), true);
813 QCOMPARE(object->property("loading").toBool(), true);
814 QCOMPARE(object->property("done").toBool(), true);
815 QCOMPARE(object->property("resetException").toBool(), true);
820 void tst_qdeclarativexmlhttprequest::status_data()
822 QTest::addColumn<QUrl>("replyUrl");
823 QTest::addColumn<int>("status");
825 QTest::newRow("OK") << TEST_FILE("status.200.reply") << 200;
826 QTest::newRow("Not Found") << TEST_FILE("status.404.reply") << 404;
829 void tst_qdeclarativexmlhttprequest::statusText()
831 QFETCH(QUrl, replyUrl);
832 QFETCH(QString, statusText);
834 TestHTTPServer server(SERVER_PORT);
835 QVERIFY(server.isValid());
836 QVERIFY(server.wait(TEST_FILE("status.expect"),
838 TEST_FILE("testdocument.html")));
840 QDeclarativeComponent component(&engine, TEST_FILE("statusText.qml"));
841 QObject *object = component.beginCreate(engine.rootContext());
842 QVERIFY(object != 0);
843 object->setProperty("url", "http://127.0.0.1:14445/testdocument.html");
844 object->setProperty("expectedStatus", statusText);
845 component.completeCreate();
847 QTRY_VERIFY(object->property("dataOK").toBool() == true);
849 QCOMPARE(object->property("unsentException").toBool(), true);
850 QCOMPARE(object->property("openedException").toBool(), true);
851 QCOMPARE(object->property("sentException").toBool(), true);
852 QCOMPARE(object->property("headersReceived").toBool(), true);
853 QCOMPARE(object->property("loading").toBool(), true);
854 QCOMPARE(object->property("done").toBool(), true);
855 QCOMPARE(object->property("resetException").toBool(), true);
860 void tst_qdeclarativexmlhttprequest::statusText_data()
862 QTest::addColumn<QUrl>("replyUrl");
863 QTest::addColumn<QString>("statusText");
865 QTest::newRow("OK") << TEST_FILE("status.200.reply") << "OK";
866 QTest::newRow("Not Found") << TEST_FILE("status.404.reply") << "Document not found";
869 void tst_qdeclarativexmlhttprequest::responseText()
871 QFETCH(QUrl, replyUrl);
872 QFETCH(QUrl, bodyUrl);
873 QFETCH(QString, responseText);
875 TestHTTPServer server(SERVER_PORT);
876 QVERIFY(server.isValid());
877 QVERIFY(server.wait(TEST_FILE("status.expect"),
881 QDeclarativeComponent component(&engine, TEST_FILE("responseText.qml"));
882 QObject *object = component.beginCreate(engine.rootContext());
883 QVERIFY(object != 0);
884 object->setProperty("url", "http://127.0.0.1:14445/testdocument.html");
885 object->setProperty("expectedText", responseText);
886 component.completeCreate();
888 QTRY_VERIFY(object->property("dataOK").toBool() == true);
890 QCOMPARE(object->property("unsent").toBool(), true);
891 QCOMPARE(object->property("opened").toBool(), true);
892 QCOMPARE(object->property("sent").toBool(), true);
893 QCOMPARE(object->property("headersReceived").toBool(), true);
894 QCOMPARE(object->property("loading").toBool(), true);
895 QCOMPARE(object->property("done").toBool(), true);
896 QCOMPARE(object->property("reset").toBool(), true);
901 void tst_qdeclarativexmlhttprequest::responseText_data()
903 QTest::addColumn<QUrl>("replyUrl");
904 QTest::addColumn<QUrl>("bodyUrl");
905 QTest::addColumn<QString>("responseText");
907 QTest::newRow("OK") << TEST_FILE("status.200.reply") << TEST_FILE("testdocument.html") << "QML Rocks!\n";
908 QTest::newRow("empty body") << TEST_FILE("status.200.reply") << QUrl() << "";
909 QTest::newRow("Not Found") << TEST_FILE("status.404.reply") << TEST_FILE("testdocument.html") << "";
912 void tst_qdeclarativexmlhttprequest::nonUtf8()
914 QFETCH(QString, fileName);
915 QFETCH(QString, responseText);
916 QFETCH(QString, xmlRootNodeValue);
918 QDeclarativeComponent component(&engine, TEST_FILE("utf16.qml"));
919 QObject *object = component.create();
920 QVERIFY(object != 0);
922 object->setProperty("fileName", fileName);
923 QMetaObject::invokeMethod(object, "startRequest");
925 QTRY_VERIFY(object->property("dataOK").toBool() == true);
927 QCOMPARE(object->property("responseText").toString(), responseText);
929 if (!xmlRootNodeValue.isEmpty()) {
930 QString rootNodeValue = object->property("responseXmlRootNodeValue").toString();
931 QCOMPARE(rootNodeValue, xmlRootNodeValue);
937 void tst_qdeclarativexmlhttprequest::nonUtf8_data()
939 QTest::addColumn<QString>("fileName");
940 QTest::addColumn<QString>("responseText");
941 QTest::addColumn<QString>("xmlRootNodeValue");
945 uc[0] = QChar(0x10e3);
947 uc[2] = QChar(0x03a3);
949 QTest::newRow("responseText") << "utf16.html" << uc + '\n' << "";
950 QTest::newRow("responseXML") << "utf16.xml" << "<?xml version=\"1.0\" encoding=\"UTF-16\" standalone='yes'?>\n<root>\n" + uc + "\n</root>\n" << QString('\n' + uc + '\n');
953 // Test that calling hte XMLHttpRequest methods on a non-XMLHttpRequest object
954 // throws an exception
955 void tst_qdeclarativexmlhttprequest::invalidMethodUsage()
957 QDeclarativeComponent component(&engine, TEST_FILE("invalidMethodUsage.qml"));
958 QObject *object = component.create();
959 QVERIFY(object != 0);
961 QCOMPARE(object->property("onreadystatechange").toBool(), true);
962 QCOMPARE(object->property("readyState").toBool(), true);
963 QCOMPARE(object->property("status").toBool(), true);
964 QCOMPARE(object->property("statusText").toBool(), true);
965 QCOMPARE(object->property("responseText").toBool(), true);
966 QCOMPARE(object->property("responseXML").toBool(), true);
968 QCOMPARE(object->property("open").toBool(), true);
969 QCOMPARE(object->property("setRequestHeader").toBool(), true);
970 QCOMPARE(object->property("send").toBool(), true);
971 QCOMPARE(object->property("abort").toBool(), true);
972 QCOMPARE(object->property("getResponseHeader").toBool(), true);
973 QCOMPARE(object->property("getAllResponseHeaders").toBool(), true);
978 // Test that XMLHttpRequest transparently redirects
979 void tst_qdeclarativexmlhttprequest::redirects()
982 TestHTTPServer server(SERVER_PORT);
983 QVERIFY(server.isValid());
984 server.addRedirect("redirect.html", "http://127.0.0.1:14445/redirecttarget.html");
985 server.serveDirectory(SRCDIR "/data");
987 QDeclarativeComponent component(&engine, TEST_FILE("redirects.qml"));
988 QObject *object = component.beginCreate(engine.rootContext());
989 QVERIFY(object != 0);
990 object->setProperty("url", "http://127.0.0.1:14445/redirect.html");
991 object->setProperty("expectedText", "");
992 component.completeCreate();
994 QTRY_VERIFY(object->property("done").toBool() == true);
995 QCOMPARE(object->property("dataOK").toBool(), true);
1001 TestHTTPServer server(SERVER_PORT);
1002 QVERIFY(server.isValid());
1003 server.addRedirect("redirect.html", "http://127.0.0.1:14445/redirectmissing.html");
1004 server.serveDirectory(SRCDIR "/data");
1006 QDeclarativeComponent component(&engine, TEST_FILE("redirectError.qml"));
1007 QObject *object = component.beginCreate(engine.rootContext());
1008 QVERIFY(object != 0);
1009 object->setProperty("url", "http://127.0.0.1:14445/redirect.html");
1010 object->setProperty("expectedText", "");
1011 component.completeCreate();
1013 QTRY_VERIFY(object->property("done").toBool() == true);
1014 QCOMPARE(object->property("dataOK").toBool(), true);
1020 TestHTTPServer server(SERVER_PORT);
1021 QVERIFY(server.isValid());
1022 server.addRedirect("redirect.html", "http://127.0.0.1:14445/redirect.html");
1023 server.serveDirectory(SRCDIR "/data");
1025 QDeclarativeComponent component(&engine, TEST_FILE("redirectRecur.qml"));
1026 QObject *object = component.beginCreate(engine.rootContext());
1027 QVERIFY(object != 0);
1028 object->setProperty("url", "http://127.0.0.1:14445/redirect.html");
1029 object->setProperty("expectedText", "");
1030 component.completeCreate();
1032 for (int ii = 0; ii < 60; ++ii) {
1033 if (object->property("done").toBool()) break;
1036 QVERIFY(object->property("done").toBool() == true);
1038 QCOMPARE(object->property("dataOK").toBool(), true);
1044 void tst_qdeclarativexmlhttprequest::responseXML_invalid()
1046 QDeclarativeComponent component(&engine, TEST_FILE("responseXML_invalid.qml"));
1047 QObject *object = component.create();
1048 QVERIFY(object != 0);
1050 QTRY_VERIFY(object->property("dataOK").toBool() == true);
1052 QCOMPARE(object->property("xmlNull").toBool(), true);
1057 // Test the Document DOM element
1058 void tst_qdeclarativexmlhttprequest::document()
1060 QDeclarativeComponent component(&engine, TEST_FILE("document.qml"));
1061 QObject *object = component.create();
1062 QVERIFY(object != 0);
1064 QTRY_VERIFY(object->property("dataOK").toBool() == true);
1066 QCOMPARE(object->property("xmlTest").toBool(), true);
1071 // Test the Element DOM element
1072 void tst_qdeclarativexmlhttprequest::element()
1074 QDeclarativeComponent component(&engine, TEST_FILE("element.qml"));
1075 QObject *object = component.create();
1076 QVERIFY(object != 0);
1078 QTRY_VERIFY(object->property("dataOK").toBool() == true);
1080 QCOMPARE(object->property("xmlTest").toBool(), true);
1085 // Test the Attr DOM element
1086 void tst_qdeclarativexmlhttprequest::attr()
1088 QDeclarativeComponent component(&engine, TEST_FILE("attr.qml"));
1089 QObject *object = component.create();
1090 QVERIFY(object != 0);
1092 QTRY_VERIFY(object->property("dataOK").toBool() == true);
1094 QCOMPARE(object->property("xmlTest").toBool(), true);
1099 // Test the Text DOM element
1100 void tst_qdeclarativexmlhttprequest::text()
1102 QDeclarativeComponent component(&engine, TEST_FILE("text.qml"));
1103 QObject *object = component.create();
1104 QVERIFY(object != 0);
1106 QTRY_VERIFY(object->property("dataOK").toBool() == true);
1108 QCOMPARE(object->property("xmlTest").toBool(), true);
1113 // Test the CDataSection DOM element
1114 void tst_qdeclarativexmlhttprequest::cdata()
1116 QDeclarativeComponent component(&engine, TEST_FILE("cdata.qml"));
1117 QObject *object = component.create();
1118 QVERIFY(object != 0);
1120 QTRY_VERIFY(object->property("dataOK").toBool() == true);
1122 QCOMPARE(object->property("xmlTest").toBool(), true);
1127 QTEST_MAIN(tst_qdeclarativexmlhttprequest)
1129 #include "tst_qdeclarativexmlhttprequest.moc"