Files
pay/testing/payment/TestPayment.cpp
T

272 lines
9.5 KiB
C++

/*
* 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"
#include <Payment.h>
#include <PaymentDetailOutput_p.h>
#include <RepeatPaymentDetails.h>
#include <QStandardPaths>
#include <Wallet.h>
#include <qtest.h>
#include <qtestcase.h>
#include <primitives/script.h>
std::unique_ptr<Wallet> TestPayment::createWallet()
{
if (m_dir.isEmpty()) {
QString basedir = QStandardPaths::writableLocation(QStandardPaths::TempLocation);
m_dir = basedir + QString("/floweepay-%1/").arg(QCoreApplication::instance()->applicationPid());
}
std::unique_ptr<Wallet> wallet(Wallet::createWallet(m_dir.toStdString(), 1111, "test"));
return wallet;
}
void TestPayment::basic()
{
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");
auto pool = std::make_shared<Streaming::BufferPool>();
saveFile = payment.save(pool);
}
auto dummy = createWallet();
{
Payment payment(saveFile, dummy.get());
QCOMPARE(payment.feePerByte(), 80);
QCOMPARE(payment.paymentAmount(), 1001000);
QCOMPARE(payment.paymentAmountFiat(), 400);
QCOMPARE(payment.userComment(), "my comment");
}
}
void TestPayment::saveOutput()
{
auto pool = std::make_shared<Streaming::BufferPool>();
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");
saveFile = payment.save(pool);
}
auto dummy = createWallet();
{
Payment payment(saveFile, dummy.get());
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);
saveFile = payment.save(pool);
}
pool->write("someScript");
Streaming::ConstBuffer outScript = pool->commit();
QCOMPARE(outScript.size(), 10);
{
Payment payment(saveFile, dummy.get());
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());
saveFile = payment.save(pool);
}
{
Payment payment(saveFile, dummy.get());
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()
{
auto pool = std::make_shared<Streaming::BufferPool>();
Streaming::ConstBuffer saveFile;
{
Payment payment;
payment.setFiatPrice(40000); // price per coin.
QCOMPARE(payment.repeatDetails(), nullptr);
payment.makeRepeating();
auto *r = payment.repeatDetails();
QVERIFY(r != nullptr);
// first an empty one.
saveFile = payment.save(pool);
}
auto dummy = createWallet();
{
Payment payment;
QCOMPARE(payment.repeatDetails(), nullptr);
payment.makeRepeating();
auto *r = payment.repeatDetails();
QVERIFY(r != nullptr);
r->addRepeatDayOfMonth(30, 1, 4);
r->addRepeatDayOfMonth(7);
r->addRepeatDayOfMonth(9, 2);
saveFile = payment.save(pool);
}
{
Payment payment(saveFile, dummy.get());
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);
r->setSunset(QDate(2030, 10, 30));
confs = r->repeatConfig();
confs[0].baseDate = QDateTime(QDate(2025, 05, 3), QTime(14,00));
r->setRepeatConfig(confs);
QCOMPARE(r->currencyLocale(), "");
QCOMPARE(r->enabled(), true);
QCOMPARE(r->autoApprove(), false);
r->setCurrencyLocale("en_FL");
r->setEnabled(false);
r->setAutoApprove(true);
saveFile = payment.save(pool);
}
{
Payment payment(saveFile, dummy.get());
auto *r = payment.repeatDetails();
QVERIFY(r != nullptr);
QCOMPARE(r->sunset(), QDate(2030, 10, 30));
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)));
QCOMPARE(r->currencyLocale(), "en_FL");
QCOMPARE(r->enabled(), false);
QCOMPARE(r->autoApprove(), true);
// saveFile = payment.save(pool);
}
}
void TestPayment::next()
{
const QTime time(13, 34);
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));
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));
// 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());
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));
}
QTEST_MAIN(TestPayment)