2025-06-07 22:23:34 +02:00
|
|
|
/*
|
|
|
|
|
* This file is part of the Flowee project
|
|
|
|
|
* Copyright (C) 2025 Tom Zander <tom@flowee.org>
|
|
|
|
|
*
|
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
* (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
*/
|
|
|
|
|
#include "TestPayment.h"
|
|
|
|
|
|
2025-06-08 12:46:00 +02:00
|
|
|
#include <Payment.h>
|
|
|
|
|
#include <PaymentDetailOutput_p.h>
|
2025-06-20 18:31:18 +02:00
|
|
|
#include <RepeatPaymentDetails.h>
|
2025-06-08 12:46:00 +02:00
|
|
|
#include <QStandardPaths>
|
|
|
|
|
#include <Wallet.h>
|
2025-06-07 22:23:34 +02:00
|
|
|
#include <qtest.h>
|
|
|
|
|
#include <qtestcase.h>
|
|
|
|
|
|
2025-06-08 12:46:00 +02:00
|
|
|
#include <primitives/script.h>
|
|
|
|
|
|
2025-10-08 15:35:34 +02:00
|
|
|
std::shared_ptr<Wallet> TestPayment::createWallet()
|
2025-06-08 12:46:00 +02:00
|
|
|
{
|
|
|
|
|
if (m_dir.isEmpty()) {
|
|
|
|
|
QString basedir = QStandardPaths::writableLocation(QStandardPaths::TempLocation);
|
|
|
|
|
m_dir = basedir + QString("/floweepay-%1/").arg(QCoreApplication::instance()->applicationPid());
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-08 15:35:34 +02:00
|
|
|
return Wallet::createWallet(m_dir.toStdString(), 1111, "test");
|
2025-06-08 12:46:00 +02:00
|
|
|
}
|
|
|
|
|
|
2025-06-07 22:23:34 +02:00
|
|
|
void TestPayment::basic()
|
|
|
|
|
{
|
2025-06-08 12:46:00 +02:00
|
|
|
Streaming::ConstBuffer saveFile;
|
|
|
|
|
{
|
|
|
|
|
Payment payment;
|
|
|
|
|
payment.setPaymentAmount(1001000);
|
|
|
|
|
payment.setUserComment("my comment");
|
|
|
|
|
QCOMPARE(payment.paymentAmount(), 1001000);
|
|
|
|
|
payment.setFeePerByte(80);
|
|
|
|
|
payment.setFiatPrice(40000); // price per coin.
|
|
|
|
|
QCOMPARE(payment.feePerByte(), 80);
|
|
|
|
|
QCOMPARE(payment.paymentAmount(), 1001000);
|
|
|
|
|
QCOMPARE(payment.paymentAmountFiat(), 400);
|
|
|
|
|
QCOMPARE(payment.userComment(), "my comment");
|
|
|
|
|
|
2025-06-22 21:44:33 +02:00
|
|
|
auto pool = std::make_shared<Streaming::BufferPool>();
|
|
|
|
|
saveFile = payment.save(pool);
|
2025-06-08 12:46:00 +02:00
|
|
|
}
|
|
|
|
|
auto dummy = createWallet();
|
|
|
|
|
{
|
2025-10-08 15:35:34 +02:00
|
|
|
Payment payment(saveFile, dummy);
|
2025-06-08 12:46:00 +02:00
|
|
|
QCOMPARE(payment.feePerByte(), 80);
|
|
|
|
|
QCOMPARE(payment.paymentAmount(), 1001000);
|
|
|
|
|
QCOMPARE(payment.paymentAmountFiat(), 400);
|
|
|
|
|
QCOMPARE(payment.userComment(), "my comment");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TestPayment::saveOutput()
|
|
|
|
|
{
|
2025-06-22 21:44:33 +02:00
|
|
|
auto pool = std::make_shared<Streaming::BufferPool>();
|
2025-06-08 12:46:00 +02:00
|
|
|
Streaming::ConstBuffer saveFile;
|
|
|
|
|
{
|
|
|
|
|
Payment payment;
|
|
|
|
|
payment.setFiatPrice(40000); // price per coin.
|
|
|
|
|
auto det = payment.paymentDetails();
|
|
|
|
|
QCOMPARE(det.size() , 1);
|
|
|
|
|
auto *out = qobject_cast<PaymentDetailOutput*>(det.at(0));
|
|
|
|
|
QVERIFY(out != nullptr);
|
|
|
|
|
out->setPaymentAmount(999011124);
|
|
|
|
|
out->setFiatFollows(true);
|
|
|
|
|
out->setAddress("hello");
|
|
|
|
|
|
2025-06-22 21:44:33 +02:00
|
|
|
saveFile = payment.save(pool);
|
2025-06-08 12:46:00 +02:00
|
|
|
}
|
|
|
|
|
auto dummy = createWallet();
|
|
|
|
|
{
|
2025-10-08 15:35:34 +02:00
|
|
|
Payment payment(saveFile, dummy);
|
2025-06-08 12:46:00 +02:00
|
|
|
auto det = payment.paymentDetails();
|
|
|
|
|
QCOMPARE(det.size() , 1);
|
|
|
|
|
auto *out = qobject_cast<PaymentDetailOutput*>(det.at(0));
|
|
|
|
|
QVERIFY(out != nullptr);
|
|
|
|
|
QCOMPARE(out->paymentAmount(), 999011124);
|
|
|
|
|
QCOMPARE(out->fiatFollows(), true);
|
|
|
|
|
QVERIFY(out->outputScript().isEmpty());
|
|
|
|
|
QCOMPARE(out->address(), "hello");
|
|
|
|
|
QCOMPARE(payment.repeatDetails(), nullptr);
|
|
|
|
|
|
|
|
|
|
const auto copy = out->paymentAmountFiat();
|
|
|
|
|
out->setFiatFollows(false);
|
|
|
|
|
out->setPaymentAmountFiat(copy);
|
2025-06-22 21:44:33 +02:00
|
|
|
saveFile = payment.save(pool);
|
2025-06-08 12:46:00 +02:00
|
|
|
}
|
|
|
|
|
|
2025-06-22 21:44:33 +02:00
|
|
|
pool->write("someScript");
|
|
|
|
|
Streaming::ConstBuffer outScript = pool->commit();
|
2025-06-08 12:46:00 +02:00
|
|
|
QCOMPARE(outScript.size(), 10);
|
|
|
|
|
{
|
2025-10-08 15:35:34 +02:00
|
|
|
Payment payment(saveFile, dummy);
|
2025-06-08 12:46:00 +02:00
|
|
|
auto det = payment.paymentDetails();
|
|
|
|
|
QCOMPARE(det.size() , 1);
|
|
|
|
|
auto *out = qobject_cast<PaymentDetailOutput*>(det.at(0));
|
|
|
|
|
QVERIFY(out != nullptr);
|
|
|
|
|
QCOMPARE(out->fiatFollows(), false);
|
|
|
|
|
QCOMPARE(out->paymentAmount(), 999010000); // some rounding.
|
|
|
|
|
QVERIFY(out->outputScript().isEmpty());
|
|
|
|
|
QCOMPARE(out->address(), "hello");
|
|
|
|
|
QCOMPARE(payment.repeatDetails(), nullptr);
|
|
|
|
|
|
|
|
|
|
out->setOutputScript(outScript);
|
|
|
|
|
QVERIFY(out->address().isEmpty());
|
2025-06-22 21:44:33 +02:00
|
|
|
saveFile = payment.save(pool);
|
2025-06-08 12:46:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
2025-10-08 15:35:34 +02:00
|
|
|
Payment payment(saveFile, dummy);
|
2025-06-08 12:46:00 +02:00
|
|
|
auto det = payment.paymentDetails();
|
|
|
|
|
QCOMPARE(det.size() , 1);
|
|
|
|
|
auto *out = qobject_cast<PaymentDetailOutput*>(det.at(0));
|
|
|
|
|
QVERIFY(out != nullptr);
|
|
|
|
|
QCOMPARE(out->fiatFollows(), false);
|
|
|
|
|
QCOMPARE(out->paymentAmount(), 999010000);
|
|
|
|
|
QCOMPARE(out->outputScript(), outScript);
|
|
|
|
|
QVERIFY(out->address().isEmpty());
|
|
|
|
|
QCOMPARE(payment.repeatDetails(), nullptr);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TestPayment::saveRepeat()
|
|
|
|
|
{
|
2025-06-22 21:44:33 +02:00
|
|
|
auto pool = std::make_shared<Streaming::BufferPool>();
|
2025-06-20 18:31:18 +02:00
|
|
|
Streaming::ConstBuffer saveFile;
|
|
|
|
|
{
|
|
|
|
|
Payment payment;
|
|
|
|
|
payment.setFiatPrice(40000); // price per coin.
|
|
|
|
|
QCOMPARE(payment.repeatDetails(), nullptr);
|
|
|
|
|
payment.makeRepeating();
|
|
|
|
|
auto *r = payment.repeatDetails();
|
|
|
|
|
QVERIFY(r != nullptr);
|
2025-06-22 19:51:19 +02:00
|
|
|
// first an empty one.
|
2025-06-22 21:44:33 +02:00
|
|
|
saveFile = payment.save(pool);
|
2025-06-20 18:31:18 +02:00
|
|
|
}
|
|
|
|
|
auto dummy = createWallet();
|
|
|
|
|
{
|
|
|
|
|
Payment payment;
|
|
|
|
|
QCOMPARE(payment.repeatDetails(), nullptr);
|
|
|
|
|
payment.makeRepeating();
|
|
|
|
|
auto *r = payment.repeatDetails();
|
|
|
|
|
QVERIFY(r != nullptr);
|
|
|
|
|
|
2025-06-22 19:51:19 +02:00
|
|
|
r->addRepeatDayOfMonth(30, 1, 4);
|
|
|
|
|
r->addRepeatDayOfMonth(7);
|
|
|
|
|
r->addRepeatDayOfMonth(9, 2);
|
|
|
|
|
saveFile = payment.save(pool);
|
|
|
|
|
}
|
|
|
|
|
{
|
2025-10-08 15:35:34 +02:00
|
|
|
Payment payment(saveFile, dummy);
|
2025-06-22 19:51:19 +02:00
|
|
|
auto *r = payment.repeatDetails();
|
|
|
|
|
QVERIFY(r != nullptr);
|
|
|
|
|
QVERIFY(!r->sunset().isValid());
|
|
|
|
|
auto confs = r->repeatConfig();
|
|
|
|
|
QCOMPARE(confs.size(), 3);
|
|
|
|
|
auto conf = confs.at(0); // they get sorted on insert.
|
|
|
|
|
QCOMPARE(conf.dayOfMonth, 7);
|
|
|
|
|
QCOMPARE(conf.dayOfWeek, -1);
|
|
|
|
|
QCOMPARE(conf.weekInterval, -1);
|
|
|
|
|
QCOMPARE(conf.monthInterval, -1);
|
|
|
|
|
conf = confs.at(1);
|
|
|
|
|
QCOMPARE(conf.dayOfMonth, 9);
|
|
|
|
|
QCOMPARE(conf.dayOfWeek, -1);
|
|
|
|
|
QCOMPARE(conf.weekInterval, 2);
|
|
|
|
|
QCOMPARE(conf.monthInterval, -1);
|
|
|
|
|
conf = confs.at(2);
|
|
|
|
|
QCOMPARE(conf.dayOfMonth, 30);
|
|
|
|
|
QCOMPARE(conf.dayOfWeek, -1);
|
|
|
|
|
QCOMPARE(conf.weekInterval, 1);
|
|
|
|
|
QCOMPARE(conf.monthInterval, 4);
|
|
|
|
|
|
|
|
|
|
r->setRepeatConfig(QVector<RepeatPaymentDetails::Config>()); // clear
|
|
|
|
|
r->addRepeatRelative(1, 4);
|
2025-06-21 20:39:39 +02:00
|
|
|
r->setSunset(QDate(2030, 10, 30));
|
2025-06-22 19:51:19 +02:00
|
|
|
confs = r->repeatConfig();
|
|
|
|
|
confs[0].baseDate = QDateTime(QDate(2025, 05, 3), QTime(14,00));
|
|
|
|
|
r->setRepeatConfig(confs);
|
2025-06-20 18:31:18 +02:00
|
|
|
|
2025-06-24 08:47:06 +02:00
|
|
|
QCOMPARE(r->currencyLocale(), "");
|
|
|
|
|
QCOMPARE(r->enabled(), true);
|
|
|
|
|
QCOMPARE(r->autoApprove(), false);
|
|
|
|
|
r->setCurrencyLocale("en_FL");
|
|
|
|
|
r->setEnabled(false);
|
|
|
|
|
r->setAutoApprove(true);
|
|
|
|
|
|
2025-06-22 21:44:33 +02:00
|
|
|
saveFile = payment.save(pool);
|
2025-06-20 18:31:18 +02:00
|
|
|
}
|
|
|
|
|
{
|
2025-10-08 15:35:34 +02:00
|
|
|
Payment payment(saveFile, dummy);
|
2025-06-20 18:31:18 +02:00
|
|
|
auto *r = payment.repeatDetails();
|
|
|
|
|
QVERIFY(r != nullptr);
|
2025-06-21 20:39:39 +02:00
|
|
|
QCOMPARE(r->sunset(), QDate(2030, 10, 30));
|
2025-06-22 19:51:19 +02:00
|
|
|
auto confs = r->repeatConfig();
|
|
|
|
|
QCOMPARE(confs.size(), 1);
|
|
|
|
|
auto conf = confs.at(0);
|
|
|
|
|
QCOMPARE(conf.dayOfMonth, -1);
|
|
|
|
|
QCOMPARE(conf.dayOfWeek, 1);
|
|
|
|
|
QCOMPARE(conf.weekInterval, 4);
|
|
|
|
|
QCOMPARE(conf.monthInterval, -1);
|
|
|
|
|
QCOMPARE(conf.baseDate, QDateTime(QDate(2025, 05, 3), QTime(14,00)));
|
2025-06-24 08:47:06 +02:00
|
|
|
QCOMPARE(r->currencyLocale(), "en_FL");
|
|
|
|
|
QCOMPARE(r->enabled(), false);
|
|
|
|
|
QCOMPARE(r->autoApprove(), true);
|
2025-06-22 19:51:19 +02:00
|
|
|
// saveFile = payment.save(pool);
|
2025-06-20 18:31:18 +02:00
|
|
|
}
|
2025-06-07 22:23:34 +02:00
|
|
|
}
|
|
|
|
|
|
2025-06-21 20:39:39 +02:00
|
|
|
void TestPayment::next()
|
|
|
|
|
{
|
|
|
|
|
const QTime time(13, 34);
|
2025-06-22 19:51:19 +02:00
|
|
|
RepeatPaymentDetails::Config config;
|
|
|
|
|
config.dayOfMonth = 13;
|
|
|
|
|
config.baseDate = QDateTime(QDate(2025, 3, 20), time);
|
|
|
|
|
QCOMPARE(config.next(), QDateTime(QDate(2025, 4, 13), time));
|
|
|
|
|
config.monthInterval = 3;
|
|
|
|
|
QCOMPARE(config.next(), QDateTime(QDate(2025, 6, 13), time));
|
|
|
|
|
config.monthInterval = -1;
|
|
|
|
|
QCOMPARE(config.next(), QDateTime(QDate(2025, 4, 13), time));
|
2025-06-21 20:39:39 +02:00
|
|
|
|
2025-06-22 19:51:19 +02:00
|
|
|
config.baseDate = QDateTime(QDate(2025, 1, 30), time);
|
|
|
|
|
QCOMPARE(config.next(), QDateTime(QDate(2025, 2, 13), time));
|
|
|
|
|
config.baseDate = QDateTime(QDate(2025, 2, 13), time);
|
|
|
|
|
QCOMPARE(config.next(), QDateTime(QDate(2025, 3, 13), time));
|
|
|
|
|
config.monthInterval = 3;
|
|
|
|
|
QCOMPARE(config.next(), QDateTime(QDate(2025, 5, 13), time));
|
|
|
|
|
|
2025-06-27 21:03:06 +02:00
|
|
|
// impossible date handling
|
|
|
|
|
config.baseDate = QDateTime(QDate(2025, 2, 4), time);
|
|
|
|
|
config.dayOfMonth = 31;
|
|
|
|
|
config.monthInterval = 3;
|
|
|
|
|
// As feb 31 is impossible, I expect it to be May due to the 3 month interval
|
|
|
|
|
QCOMPARE(config.next(), QDateTime(QDate(2025, 5, 31), time));
|
|
|
|
|
config.monthInterval = 12; // an impossible repeat
|
|
|
|
|
QVERIFY(!config.next().isValid());
|
|
|
|
|
|
2025-06-22 19:51:19 +02:00
|
|
|
|
|
|
|
|
config = RepeatPaymentDetails::Config();
|
|
|
|
|
config.dayOfWeek = 2; // tuesday
|
|
|
|
|
config.baseDate = QDateTime(QDate(2025, 3, 20), time);
|
|
|
|
|
QCOMPARE(config.next(), QDateTime(QDate(2025, 3, 25), time));
|
|
|
|
|
config.baseDate = QDateTime(QDate(2025, 3, 25), time);
|
|
|
|
|
QCOMPARE(config.next(), QDateTime(QDate(2025, 4, 1), time));
|
|
|
|
|
config.weekInterval = 2;
|
|
|
|
|
QCOMPARE(config.next(), QDateTime(QDate(2025, 4, 8), time));
|
|
|
|
|
config.weekInterval = 3;
|
|
|
|
|
QCOMPARE(config.next(), QDateTime(QDate(2025, 4, 15), time));
|
|
|
|
|
config.weekInterval = 7;
|
|
|
|
|
QCOMPARE(config.next(), QDateTime(QDate(2025, 5, 13), time));
|
|
|
|
|
config.weekInterval = 0;
|
|
|
|
|
config.monthInterval = 2;
|
|
|
|
|
QCOMPARE(config.next(), QDateTime(QDate(2025, 5, 27), time));
|
2025-06-21 20:39:39 +02:00
|
|
|
}
|
|
|
|
|
|
2025-06-07 22:23:34 +02:00
|
|
|
QTEST_MAIN(TestPayment)
|