testxmlparse.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  1. /*
  2. * This software is in the public domain, furnished "as is", without technical
  3. * support, and with no warranty, express or implied, as to its usefulness for
  4. * any purpose.
  5. * */
  6. #include <QtTest>
  7. #include "networkjobs.h"
  8. using namespace OCC;
  9. class TestXmlParse : public QObject
  10. {
  11. Q_OBJECT
  12. private:
  13. bool _success;
  14. QStringList _subdirs;
  15. QStringList _items;
  16. public slots:
  17. void slotDirectoryListingSubFolders(const QStringList& list)
  18. {
  19. qDebug() << "subfolders: " << list;
  20. _subdirs.append(list);
  21. }
  22. void slotDirectoryListingIterated(const QString& item, const QMap<QString,QString>& )
  23. {
  24. qDebug() << " item: " << item;
  25. _items.append(item);
  26. }
  27. void slotFinishedSuccessfully()
  28. {
  29. _success = true;
  30. }
  31. private slots:
  32. void init() {
  33. qDebug() << Q_FUNC_INFO;
  34. _success = false;
  35. _subdirs.clear();
  36. _items.clear();
  37. }
  38. void cleanup() {
  39. }
  40. void testParser1() {
  41. const QByteArray testXml = "<?xml version='1.0' encoding='utf-8'?>"
  42. "<d:multistatus xmlns:d=\"DAV:\" xmlns:s=\"http://sabredav.org/ns\" xmlns:oc=\"http://owncloud.org/ns\">"
  43. "<d:response>"
  44. "<d:href>/oc/remote.php/webdav/sharefolder/</d:href>"
  45. "<d:propstat>"
  46. "<d:prop>"
  47. "<oc:id>00004213ocobzus5kn6s</oc:id>"
  48. "<oc:permissions>RDNVCK</oc:permissions>"
  49. "<oc:size>121780</oc:size>"
  50. "<d:getetag>\"5527beb0400b0\"</d:getetag>"
  51. "<d:resourcetype>"
  52. "<d:collection/>"
  53. "</d:resourcetype>"
  54. "<d:getlastmodified>Fri, 06 Feb 2015 13:49:55 GMT</d:getlastmodified>"
  55. "</d:prop>"
  56. "<d:status>HTTP/1.1 200 OK</d:status>"
  57. "</d:propstat>"
  58. "<d:propstat>"
  59. "<d:prop>"
  60. "<d:getcontentlength/>"
  61. "<oc:downloadURL/>"
  62. "<oc:dDC/>"
  63. "</d:prop>"
  64. "<d:status>HTTP/1.1 404 Not Found</d:status>"
  65. "</d:propstat>"
  66. "</d:response>"
  67. "<d:response>"
  68. "<d:href>/oc/remote.php/webdav/sharefolder/quitte.pdf</d:href>"
  69. "<d:propstat>"
  70. "<d:prop>"
  71. "<oc:id>00004215ocobzus5kn6s</oc:id>"
  72. "<oc:permissions>RDNVW</oc:permissions>"
  73. "<d:getetag>\"2fa2f0d9ed49ea0c3e409d49e652dea0\"</d:getetag>"
  74. "<d:resourcetype/>"
  75. "<d:getlastmodified>Fri, 06 Feb 2015 13:49:55 GMT</d:getlastmodified>"
  76. "<d:getcontentlength>121780</d:getcontentlength>"
  77. "</d:prop>"
  78. "<d:status>HTTP/1.1 200 OK</d:status>"
  79. "</d:propstat>"
  80. "<d:propstat>"
  81. "<d:prop>"
  82. "<oc:downloadURL/>"
  83. "<oc:dDC/>"
  84. "</d:prop>"
  85. "<d:status>HTTP/1.1 404 Not Found</d:status>"
  86. "</d:propstat>"
  87. "</d:response>"
  88. "</d:multistatus>";
  89. LsColXMLParser parser;
  90. connect( &parser, SIGNAL(directoryListingSubfolders(const QStringList&)),
  91. this, SLOT(slotDirectoryListingSubFolders(const QStringList&)) );
  92. connect( &parser, SIGNAL(directoryListingIterated(const QString&, const QMap<QString,QString>&)),
  93. this, SLOT(slotDirectoryListingIterated(const QString&, const QMap<QString,QString>&)) );
  94. connect( &parser, SIGNAL(finishedWithoutError()),
  95. this, SLOT(slotFinishedSuccessfully()) );
  96. QHash <QString, qint64> sizes;
  97. QVERIFY(parser.parse( testXml, &sizes, "/oc/remote.php/webdav/sharefolder" ));
  98. QVERIFY(_success);
  99. QCOMPARE(sizes.size(), 1 ); // Quota info in the XML
  100. QVERIFY(_items.contains("/oc/remote.php/webdav/sharefolder/quitte.pdf"));
  101. QVERIFY(_items.contains("/oc/remote.php/webdav/sharefolder"));
  102. QVERIFY(_items.size() == 2 );
  103. QVERIFY(_subdirs.contains("/oc/remote.php/webdav/sharefolder/"));
  104. QVERIFY(_subdirs.size() == 1);
  105. }
  106. void testParserBrokenXml() {
  107. const QByteArray testXml = "X<?xml version='1.0' encoding='utf-8'?>"
  108. "<d:multistatus xmlns:d=\"DAV:\" xmlns:s=\"http://sabredav.org/ns\" xmlns:oc=\"http://owncloud.org/ns\">"
  109. "<d:response>"
  110. "<d:href>/oc/remote.php/webdav/sharefolder/</d:href>"
  111. "<d:propstat>"
  112. "<d:prop>"
  113. "<oc:id>00004213ocobzus5kn6s</oc:id>"
  114. "<oc:permissions>RDNVCK</oc:permissions>"
  115. "<oc:size>121780</oc:size>"
  116. "<d:getetag>\"5527beb0400b0\"</d:getetag>"
  117. "<d:resourcetype>"
  118. "<d:collection/>"
  119. "</d:resourcetype>"
  120. "<d:getlastmodified>Fri, 06 Feb 2015 13:49:55 GMT</d:getlastmodified>"
  121. "</d:prop>"
  122. "<d:status>HTTP/1.1 200 OK</d:status>"
  123. "</d:propstat>"
  124. "<d:propstat>"
  125. "<d:prop>"
  126. "<d:getcontentlength/>"
  127. "<oc:downloadURL/>"
  128. "<oc:dDC/>"
  129. "</d:prop>"
  130. "<d:status>HTTP/1.1 404 Not Found</d:status>"
  131. "</d:propstat>"
  132. "</d:response>"
  133. "<d:response>"
  134. "<d:href>/oc/remote.php/webdav/sharefolder/quitte.pdf</d:href>"
  135. "<d:propstat>"
  136. "<d:prop>"
  137. "<oc:id>00004215ocobzus5kn6s</oc:id>"
  138. "<oc:permissions>RDNVW</oc:permissions>"
  139. "<d:getetag>\"2fa2f0d9ed49ea0c3e409d49e652dea0\"</d:getetag>"
  140. "<d:resourcetype/>"
  141. "<d:getlastmodified>Fri, 06 Feb 2015 13:49:55 GMT</d:getlastmodified>"
  142. "<d:getcontentlength>121780</d:getcontentlength>"
  143. "</d:prop>"
  144. "<d:status>HTTP/1.1 200 OK</d:status>"
  145. "</d:propstat>"
  146. "<d:propstat>"
  147. "<d:prop>"
  148. "<oc:downloadURL/>"
  149. "<oc:dDC/>"
  150. "</d:prop>"
  151. "<d:status>HTTP/1.1 404 Not Found</d:status>"
  152. "</d:propstat>"
  153. "</d:response>"
  154. "</d:multistatus>";
  155. LsColXMLParser parser;
  156. connect( &parser, SIGNAL(directoryListingSubfolders(const QStringList&)),
  157. this, SLOT(slotDirectoryListingSubFolders(const QStringList&)) );
  158. connect( &parser, SIGNAL(directoryListingIterated(const QString&, const QMap<QString,QString>&)),
  159. this, SLOT(slotDirectoryListingIterated(const QString&, const QMap<QString,QString>&)) );
  160. connect( &parser, SIGNAL(finishedWithoutError()),
  161. this, SLOT(slotFinishedSuccessfully()) );
  162. QHash <QString, qint64> sizes;
  163. QVERIFY(false == parser.parse( testXml, &sizes, "/oc/remote.php/webdav/sharefolder" )); // verify false
  164. QVERIFY(!_success);
  165. QVERIFY(sizes.size() == 0 ); // No quota info in the XML
  166. QVERIFY(_items.size() == 0 ); // FIXME: We should change the parser to not emit during parsing but at the end
  167. QVERIFY(_subdirs.size() == 0);
  168. }
  169. void testParserEmptyXmlNoDav() {
  170. const QByteArray testXml = "<html><body>I am under construction</body></html>";
  171. LsColXMLParser parser;
  172. connect( &parser, SIGNAL(directoryListingSubfolders(const QStringList&)),
  173. this, SLOT(slotDirectoryListingSubFolders(const QStringList&)) );
  174. connect( &parser, SIGNAL(directoryListingIterated(const QString&, const QMap<QString,QString>&)),
  175. this, SLOT(slotDirectoryListingIterated(const QString&, const QMap<QString,QString>&)) );
  176. connect( &parser, SIGNAL(finishedWithoutError()),
  177. this, SLOT(slotFinishedSuccessfully()) );
  178. QHash <QString, qint64> sizes;
  179. QVERIFY(false == parser.parse( testXml, &sizes, "/oc/remote.php/webdav/sharefolder" )); // verify false
  180. QVERIFY(!_success);
  181. QVERIFY(sizes.size() == 0 ); // No quota info in the XML
  182. QVERIFY(_items.size() == 0 ); // FIXME: We should change the parser to not emit during parsing but at the end
  183. QVERIFY(_subdirs.size() == 0);
  184. }
  185. void testParserEmptyXml() {
  186. const QByteArray testXml = "";
  187. LsColXMLParser parser;
  188. connect( &parser, SIGNAL(directoryListingSubfolders(const QStringList&)),
  189. this, SLOT(slotDirectoryListingSubFolders(const QStringList&)) );
  190. connect( &parser, SIGNAL(directoryListingIterated(const QString&, const QMap<QString,QString>&)),
  191. this, SLOT(slotDirectoryListingIterated(const QString&, const QMap<QString,QString>&)) );
  192. connect( &parser, SIGNAL(finishedWithoutError()),
  193. this, SLOT(slotFinishedSuccessfully()) );
  194. QHash <QString, qint64> sizes;
  195. QVERIFY(false == parser.parse( testXml, &sizes, "/oc/remote.php/webdav/sharefolder" )); // verify false
  196. QVERIFY(!_success);
  197. QVERIFY(sizes.size() == 0 ); // No quota info in the XML
  198. QVERIFY(_items.size() == 0 ); // FIXME: We should change the parser to not emit during parsing but at the end
  199. QVERIFY(_subdirs.size() == 0);
  200. }
  201. void testParserBogfusHref1() {
  202. const QByteArray testXml = "<?xml version='1.0' encoding='utf-8'?>"
  203. "<d:multistatus xmlns:d=\"DAV:\" xmlns:s=\"http://sabredav.org/ns\" xmlns:oc=\"http://owncloud.org/ns\">"
  204. "<d:response>"
  205. "<d:href>http://127.0.0.1:81/oc/remote.php/webdav/sharefolder/</d:href>"
  206. "<d:propstat>"
  207. "<d:prop>"
  208. "<oc:id>00004213ocobzus5kn6s</oc:id>"
  209. "<oc:permissions>RDNVCK</oc:permissions>"
  210. "<oc:size>121780</oc:size>"
  211. "<d:getetag>\"5527beb0400b0\"</d:getetag>"
  212. "<d:resourcetype>"
  213. "<d:collection/>"
  214. "</d:resourcetype>"
  215. "<d:getlastmodified>Fri, 06 Feb 2015 13:49:55 GMT</d:getlastmodified>"
  216. "</d:prop>"
  217. "<d:status>HTTP/1.1 200 OK</d:status>"
  218. "</d:propstat>"
  219. "<d:propstat>"
  220. "<d:prop>"
  221. "<d:getcontentlength/>"
  222. "<oc:downloadURL/>"
  223. "<oc:dDC/>"
  224. "</d:prop>"
  225. "<d:status>HTTP/1.1 404 Not Found</d:status>"
  226. "</d:propstat>"
  227. "</d:response>"
  228. "<d:response>"
  229. "<d:href>http://127.0.0.1:81/oc/remote.php/webdav/sharefolder/quitte.pdf</d:href>"
  230. "<d:propstat>"
  231. "<d:prop>"
  232. "<oc:id>00004215ocobzus5kn6s</oc:id>"
  233. "<oc:permissions>RDNVW</oc:permissions>"
  234. "<d:getetag>\"2fa2f0d9ed49ea0c3e409d49e652dea0\"</d:getetag>"
  235. "<d:resourcetype/>"
  236. "<d:getlastmodified>Fri, 06 Feb 2015 13:49:55 GMT</d:getlastmodified>"
  237. "<d:getcontentlength>121780</d:getcontentlength>"
  238. "</d:prop>"
  239. "<d:status>HTTP/1.1 200 OK</d:status>"
  240. "</d:propstat>"
  241. "<d:propstat>"
  242. "<d:prop>"
  243. "<oc:downloadURL/>"
  244. "<oc:dDC/>"
  245. "</d:prop>"
  246. "<d:status>HTTP/1.1 404 Not Found</d:status>"
  247. "</d:propstat>"
  248. "</d:response>"
  249. "</d:multistatus>";
  250. LsColXMLParser parser;
  251. connect( &parser, SIGNAL(directoryListingSubfolders(const QStringList&)),
  252. this, SLOT(slotDirectoryListingSubFolders(const QStringList&)) );
  253. connect( &parser, SIGNAL(directoryListingIterated(const QString&, const QMap<QString,QString>&)),
  254. this, SLOT(slotDirectoryListingIterated(const QString&, const QMap<QString,QString>&)) );
  255. connect( &parser, SIGNAL(finishedWithoutError()),
  256. this, SLOT(slotFinishedSuccessfully()) );
  257. QHash <QString, qint64> sizes;
  258. QVERIFY(false == parser.parse( testXml, &sizes, "/oc/remote.php/webdav/sharefolder" ));
  259. QVERIFY(!_success);
  260. }
  261. void testParserBogfusHref2() {
  262. const QByteArray testXml = "<?xml version='1.0' encoding='utf-8'?>"
  263. "<d:multistatus xmlns:d=\"DAV:\" xmlns:s=\"http://sabredav.org/ns\" xmlns:oc=\"http://owncloud.org/ns\">"
  264. "<d:response>"
  265. "<d:href>/sharefolder</d:href>"
  266. "<d:propstat>"
  267. "<d:prop>"
  268. "<oc:id>00004213ocobzus5kn6s</oc:id>"
  269. "<oc:permissions>RDNVCK</oc:permissions>"
  270. "<oc:size>121780</oc:size>"
  271. "<d:getetag>\"5527beb0400b0\"</d:getetag>"
  272. "<d:resourcetype>"
  273. "<d:collection/>"
  274. "</d:resourcetype>"
  275. "<d:getlastmodified>Fri, 06 Feb 2015 13:49:55 GMT</d:getlastmodified>"
  276. "</d:prop>"
  277. "<d:status>HTTP/1.1 200 OK</d:status>"
  278. "</d:propstat>"
  279. "<d:propstat>"
  280. "<d:prop>"
  281. "<d:getcontentlength/>"
  282. "<oc:downloadURL/>"
  283. "<oc:dDC/>"
  284. "</d:prop>"
  285. "<d:status>HTTP/1.1 404 Not Found</d:status>"
  286. "</d:propstat>"
  287. "</d:response>"
  288. "<d:response>"
  289. "<d:href>/sharefolder/quitte.pdf</d:href>"
  290. "<d:propstat>"
  291. "<d:prop>"
  292. "<oc:id>00004215ocobzus5kn6s</oc:id>"
  293. "<oc:permissions>RDNVW</oc:permissions>"
  294. "<d:getetag>\"2fa2f0d9ed49ea0c3e409d49e652dea0\"</d:getetag>"
  295. "<d:resourcetype/>"
  296. "<d:getlastmodified>Fri, 06 Feb 2015 13:49:55 GMT</d:getlastmodified>"
  297. "<d:getcontentlength>121780</d:getcontentlength>"
  298. "</d:prop>"
  299. "<d:status>HTTP/1.1 200 OK</d:status>"
  300. "</d:propstat>"
  301. "<d:propstat>"
  302. "<d:prop>"
  303. "<oc:downloadURL/>"
  304. "<oc:dDC/>"
  305. "</d:prop>"
  306. "<d:status>HTTP/1.1 404 Not Found</d:status>"
  307. "</d:propstat>"
  308. "</d:response>"
  309. "</d:multistatus>";
  310. LsColXMLParser parser;
  311. connect( &parser, SIGNAL(directoryListingSubfolders(const QStringList&)),
  312. this, SLOT(slotDirectoryListingSubFolders(const QStringList&)) );
  313. connect( &parser, SIGNAL(directoryListingIterated(const QString&, const QMap<QString,QString>&)),
  314. this, SLOT(slotDirectoryListingIterated(const QString&, const QMap<QString,QString>&)) );
  315. connect( &parser, SIGNAL(finishedWithoutError()),
  316. this, SLOT(slotFinishedSuccessfully()) );
  317. QHash <QString, qint64> sizes;
  318. QVERIFY(false == parser.parse( testXml, &sizes, "/oc/remote.php/webdav/sharefolder" ));
  319. QVERIFY(!_success);
  320. }
  321. void testHrefUrlEncoding() {
  322. const QByteArray testXml = "<?xml version='1.0' encoding='utf-8'?>"
  323. "<d:multistatus xmlns:d=\"DAV:\" xmlns:s=\"http://sabredav.org/ns\" xmlns:oc=\"http://owncloud.org/ns\">"
  324. "<d:response>"
  325. "<d:href>/%C3%A4</d:href>" // a-umlaut utf8
  326. "<d:propstat>"
  327. "<d:prop>"
  328. "<oc:id>00004213ocobzus5kn6s</oc:id>"
  329. "<oc:permissions>RDNVCK</oc:permissions>"
  330. "<oc:size>121780</oc:size>"
  331. "<d:getetag>\"5527beb0400b0\"</d:getetag>"
  332. "<d:resourcetype>"
  333. "<d:collection/>"
  334. "</d:resourcetype>"
  335. "<d:getlastmodified>Fri, 06 Feb 2015 13:49:55 GMT</d:getlastmodified>"
  336. "</d:prop>"
  337. "<d:status>HTTP/1.1 200 OK</d:status>"
  338. "</d:propstat>"
  339. "<d:propstat>"
  340. "<d:prop>"
  341. "<d:getcontentlength/>"
  342. "<oc:downloadURL/>"
  343. "<oc:dDC/>"
  344. "</d:prop>"
  345. "<d:status>HTTP/1.1 404 Not Found</d:status>"
  346. "</d:propstat>"
  347. "</d:response>"
  348. "<d:response>"
  349. "<d:href>/%C3%A4/%C3%A4.pdf</d:href>"
  350. "<d:propstat>"
  351. "<d:prop>"
  352. "<oc:id>00004215ocobzus5kn6s</oc:id>"
  353. "<oc:permissions>RDNVW</oc:permissions>"
  354. "<d:getetag>\"2fa2f0d9ed49ea0c3e409d49e652dea0\"</d:getetag>"
  355. "<d:resourcetype/>"
  356. "<d:getlastmodified>Fri, 06 Feb 2015 13:49:55 GMT</d:getlastmodified>"
  357. "<d:getcontentlength>121780</d:getcontentlength>"
  358. "</d:prop>"
  359. "<d:status>HTTP/1.1 200 OK</d:status>"
  360. "</d:propstat>"
  361. "<d:propstat>"
  362. "<d:prop>"
  363. "<oc:downloadURL/>"
  364. "<oc:dDC/>"
  365. "</d:prop>"
  366. "<d:status>HTTP/1.1 404 Not Found</d:status>"
  367. "</d:propstat>"
  368. "</d:response>"
  369. "</d:multistatus>";
  370. LsColXMLParser parser;
  371. connect( &parser, SIGNAL(directoryListingSubfolders(const QStringList&)),
  372. this, SLOT(slotDirectoryListingSubFolders(const QStringList&)) );
  373. connect( &parser, SIGNAL(directoryListingIterated(const QString&, const QMap<QString,QString>&)),
  374. this, SLOT(slotDirectoryListingIterated(const QString&, const QMap<QString,QString>&)) );
  375. connect( &parser, SIGNAL(finishedWithoutError()),
  376. this, SLOT(slotFinishedSuccessfully()) );
  377. QHash <QString, qint64> sizes;
  378. QVERIFY(parser.parse( testXml, &sizes, QString::fromUtf8("/ä") ));
  379. QVERIFY(_success);
  380. QVERIFY(_items.contains(QString::fromUtf8("/ä/ä.pdf")));
  381. QVERIFY(_items.contains(QString::fromUtf8("/ä")));
  382. QVERIFY(_items.size() == 2 );
  383. QVERIFY(_subdirs.contains(QString::fromUtf8("/ä")));
  384. QVERIFY(_subdirs.size() == 1);
  385. }
  386. };
  387. #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
  388. // Qt4 does not have QTEST_GUILESS_MAIN, so we simulate it.
  389. int main(int argc, char *argv[])
  390. {
  391. QCoreApplication app(argc, argv);
  392. TestXmlParse tc;
  393. return QTest::qExec(&tc, argc, argv);
  394. }
  395. #else
  396. QTEST_GUILESS_MAIN(TestXmlParse)
  397. #endif
  398. #include "testxmlparse.moc"