diff --git a/bitcoin-qt.pro b/bitcoin-qt.pro index 678bec013..e2097fd4b 100644 --- a/bitcoin-qt.pro +++ b/bitcoin-qt.pro @@ -226,6 +226,16 @@ SOURCES += src/qt/qrcodedialog.cpp FORMS += src/qt/forms/qrcodedialog.ui } +contains(BITCOIN_QT_TEST, 1) { +SOURCES += src/qt/test/test_main.cpp \ + src/qt/test/urltests.cpp +HEADERS += src/qt/test/urltests.h +DEPENDPATH += src/qt/test +QT += testlib +TARGET = bitcoin-qt_test +DEFINES += BITCOIN_QT_TEST +} + CODECFORTR = UTF-8 # for lrelease/lupdate diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index b25216fe9..8c4b0e6c1 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -131,6 +131,7 @@ std::string _(const char* psz) return QCoreApplication::translate("bitcoin-core", psz).toStdString(); } +#ifndef BITCOIN_QT_TEST int main(int argc, char *argv[]) { // Do this early as we don't want to bother initializing if we are just calling IPC @@ -257,3 +258,4 @@ int main(int argc, char *argv[]) } return 0; } +#endif // BITCOIN_QT_TEST diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index 22d9cc738..29ef554ac 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -56,19 +56,36 @@ bool GUIUtil::parseBitcoinURL(const QUrl *url, SendCoinsRecipient *out) SendCoinsRecipient rv; rv.address = url->path(); - rv.label = url->queryItemValue("label"); - - QString amount = url->queryItemValue("amount"); - if(amount.isEmpty()) + rv.amount = 0; + QList > items = url->queryItems(); + for (QList >::iterator i = items.begin(); i != items.end(); i++) { - rv.amount = 0; - } - else // Amount is non-empty - { - if(!BitcoinUnits::parse(BitcoinUnits::BTC, amount, &rv.amount)) + bool fShouldReturnFalse = false; + if (i->first.startsWith("req-")) { - return false; + i->first.remove(0, 4); + fShouldReturnFalse = true; } + + if (i->first == "label") + { + rv.label = i->second; + fShouldReturnFalse = false; + } + else if (i->first == "amount") + { + if(!i->second.isEmpty()) + { + if(!BitcoinUnits::parse(BitcoinUnits::BTC, i->second, &rv.amount)) + { + return false; + } + } + fShouldReturnFalse = false; + } + + if (fShouldReturnFalse) + return false; } if(out) { diff --git a/src/qt/test/test_main.cpp b/src/qt/test/test_main.cpp new file mode 100644 index 000000000..0a08eafa1 --- /dev/null +++ b/src/qt/test/test_main.cpp @@ -0,0 +1,11 @@ +#include +#include + +#include "urltests.h" + +// This is all you need to run all the tests +int main(int argc, char *argv[]) +{ + URLTests test1; + QTest::qExec(&test1); +} diff --git a/src/qt/test/urltests.cpp b/src/qt/test/urltests.cpp new file mode 100644 index 000000000..5ecc84620 --- /dev/null +++ b/src/qt/test/urltests.cpp @@ -0,0 +1,68 @@ +#include "urltests.h" +#include "../guiutil.h" +#include "../walletmodel.h" + +#include + +/* +struct SendCoinsRecipient +{ + QString address; + QString label; + qint64 amount; +}; +*/ + +void URLTests::urlTests() +{ + SendCoinsRecipient rv; + QUrl url; + url.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?req-dontexist=")); + QVERIFY(!GUIUtil::parseBitcoinURL(&url, &rv)); + + url.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?dontexist=")); + QVERIFY(GUIUtil::parseBitcoinURL(&url, &rv)); + QVERIFY(rv.address == QString("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W")); + QVERIFY(rv.label == QString()); + QVERIFY(rv.amount == 0); + + url.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?label=Wikipedia Example Address")); + QVERIFY(GUIUtil::parseBitcoinURL(&url, &rv)); + QVERIFY(rv.address == QString("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W")); + QVERIFY(rv.label == QString("Wikipedia Example Address")); + QVERIFY(rv.amount == 0); + + url.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?amount=0.001")); + QVERIFY(GUIUtil::parseBitcoinURL(&url, &rv)); + QVERIFY(rv.address == QString("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W")); + QVERIFY(rv.label == QString()); + QVERIFY(rv.amount == 100000); + + url.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?amount=1.001")); + QVERIFY(GUIUtil::parseBitcoinURL(&url, &rv)); + QVERIFY(rv.address == QString("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W")); + QVERIFY(rv.label == QString()); + QVERIFY(rv.amount == 100100000); + + url.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?amount=100&label=Wikipedia Example")); + QVERIFY(GUIUtil::parseBitcoinURL(&url, &rv)); + QVERIFY(rv.address == QString("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W")); + QVERIFY(rv.amount == 10000000000); + QVERIFY(rv.label == QString("Wikipedia Example")); + + url.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?message=Wikipedia Example Address")); + QVERIFY(GUIUtil::parseBitcoinURL(&url, &rv)); + QVERIFY(rv.address == QString("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W")); + QVERIFY(rv.label == QString()); + QVERIFY(rv.label == QString()); + + // We currently dont implement the message paramenter (ok, yea, we break spec...) + url.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?req-message=Wikipedia Example Address")); + QVERIFY(!GUIUtil::parseBitcoinURL(&url, &rv)); + + url.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?amount=1,000&label=Wikipedia Example")); + QVERIFY(!GUIUtil::parseBitcoinURL(&url, &rv)); + + url.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?amount=1,000.0&label=Wikipedia Example")); + QVERIFY(!GUIUtil::parseBitcoinURL(&url, &rv)); +} diff --git a/src/qt/test/urltests.h b/src/qt/test/urltests.h new file mode 100644 index 000000000..393c51139 --- /dev/null +++ b/src/qt/test/urltests.h @@ -0,0 +1,15 @@ +#ifndef URLTESTS_H +#define URLTESTS_H + +#include +#include + +class URLTests : public QObject +{ + Q_OBJECT + +private slots: + void urlTests(); +}; + +#endif // URLTESTS_H