Files

249 lines
9.9 KiB
C++
Raw Permalink Normal View History

2022-12-13 20:07:04 +01:00
/*
* This file is part of the Flowee project
2023-02-02 12:46:30 +01:00
* Copyright (C) 2022-2023 Tom Zander <tom@flowee.org>
2022-12-13 20:07:04 +01:00
*
* 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 "TestWalletHistoryModel.h"
#include <Wallet.h>
#include <WalletHistoryModel.h>
2025-03-07 22:29:10 +01:00
#include <QStandardPaths>
#include <qtest.h>
#include <qtestcase.h>
2022-12-13 20:07:04 +01:00
class MockWalletHistoryModel : public WalletHistoryModel
{
public:
2025-10-08 15:35:34 +02:00
explicit MockWalletHistoryModel(std::shared_ptr<Wallet> &wallet)
2022-12-13 20:07:04 +01:00
: WalletHistoryModel(wallet) {}
void notifyNewTransactions(int firstNew, int count) {
appendTransactions(firstNew, count);
}
void setMockDate(const QDate &newMockDate) {
m_mockDate = newMockDate;
createMap();
}
2022-12-13 20:07:04 +01:00
protected:
uint32_t secsSinceEpochFor(int blockHeight) const override {
assert(blockHeight > 0);
assert(blockHeight <= 6000);
// lets make our blocks range from 1000 hours ago (a little over 40 days) to 'mockdate'.
2022-12-13 20:07:04 +01:00
// we define one block every 600 seconds exect, making the 1000 hours take 6000 blocks.
assert(m_mockDate.isValid());
QDateTime d(m_mockDate, QTime(12, 0, 0));
const auto mockSecsSinceEpoch = d.toSecsSinceEpoch();
return static_cast<uint32_t>(mockSecsSinceEpoch - 1000 * 3600) + blockHeight * 600;
2022-12-13 20:07:04 +01:00
}
QDate today() const override {
assert(m_mockDate.isValid());
return m_mockDate;
}
private:
QDate m_mockDate;
2022-12-13 20:07:04 +01:00
};
TestWalletHistoryModel::TestWalletHistoryModel()
{
QString basedir = QStandardPaths::writableLocation(QStandardPaths::TempLocation);
m_dir = basedir + QString("/floweepay-%1/").arg(QCoreApplication::instance()->applicationPid());
}
void TestWalletHistoryModel::cleanup()
{
if (m_dir.isEmpty())
return;
QDir dir(m_dir);
dir.removeRecursively();
m_dir.clear();
}
void TestWalletHistoryModel::basic()
{
QFETCH(QDate, date);
QFETCH(QList<QDate>, thisWeek);
QFETCH(QList<QDate>, thisMonth);
assert(date.isValid());
logCritical() << "Our TODAY:" << date.toString();
2025-10-08 15:35:34 +02:00
auto wallet = createWallet();
std::unique_ptr<MockWalletHistoryModel> model(new MockWalletHistoryModel(wallet));
model->setMockDate(date);
2022-12-13 20:07:04 +01:00
QCOMPARE(model->rowCount(), 0);
wallet->createTransactions1();
model->notifyNewTransactions(1, 6000); // wallet starts counting at 1
2026-03-02 19:23:36 +01:00
QCOMPARE(model->rowCount(), 6001); // The model auto-inserts one 'since last seen' row.
2022-12-13 20:07:04 +01:00
auto first = model->data(model->index(0, 0), WalletHistoryModel::MinedHeight);
QVERIFY(first.isValid());
QCOMPARE(first.toInt(), 6000);
first = model->data(model->index(0, 0), WalletHistoryModel::GroupId);
QVERIFY(first.isValid());
/*
* The first transaction will always be in "today", since the mock-model
* hardcodes that we have 12 hours in todays date and thus 12 * 6 = 72 blocks.
* But the amount of transactions after that are in that same group is relative
* to the picked date. Which is the reason we test various dates.
2022-12-13 20:07:04 +01:00
*
* This leads the groups to be numbered like this:
*
* 0: some month [may be twice]
2022-12-13 20:07:04 +01:00
* 1: earlier this month [optional]
* 2: earlier this week [optional]
* 3: yesterday [optional]
* 4: today
*
* Since we occupy 40 days, the spread may be any combination of those.
* i.e. 'today' may be just group-id 2 in case today is the first of this month.
*/
QVERIFY(first.toInt() >= 2);
QCOMPARE(model->groupingPeriod(first.toInt()), "Today");
auto groupId = model->data(model->index(24 * 6, 0), WalletHistoryModel::GroupId);
QVERIFY(groupId.isValid());
QVERIFY(first.toInt() > groupId.toInt());
QCOMPARE(model->groupingPeriod(groupId.toInt()), "Yesterday");
#if 0
groupId = -1;
for (int i = 0; i < 6000; ++i) {
int x = model->data(model->index(i, 0), WalletHistoryModel::GroupId).toInt();
if (x != groupId.toInt()) {
groupId = x;
logFatal() << i << model->groupingPeriod(x) << model->data(model->index(i, 0),
WalletHistoryModel::MinedDate).toDate().toString();
}
}
#endif
2022-12-13 20:07:04 +01:00
for (const auto &dayInWeek : thisWeek) {
QVERIFY(dayInWeek.isValid());
int days = dayInWeek.daysTo(date);
groupId = model->data(model->index(24 * 6 * days, 0), WalletHistoryModel::GroupId);
2022-12-13 20:07:04 +01:00
QVERIFY(groupId.isValid());
QCOMPARE(model->groupingPeriod(groupId.toInt()), "Earlier this week");
}
for (const auto &someDay : thisMonth) {
QVERIFY(someDay.isValid());
int days = someDay.daysTo(date);
groupId = model->data(model->index(24 * 6 * days, 0), WalletHistoryModel::GroupId);
2022-12-13 20:07:04 +01:00
QVERIFY(groupId.isValid());
QCOMPARE(model->groupingPeriod(groupId.toInt()), "Earlier this month");
}
}
void TestWalletHistoryModel::basic_data()
{
QTest::addColumn<QDate>("date");
QTest::addColumn<QList<QDate> >("thisWeek"); // any dates where we expect 'earlier this week' labels.
QTest::addColumn<QList<QDate> >("thisMonth"); // any dates where we expect 'earlier this month' labels.
2022-12-13 20:07:04 +01:00
QTest::newRow("basic") << QDate(2023, 1, 1)
<< QList<QDate>() // no 'earlier this week'
<< QList<QDate>(); // no 'earlier this month'
QTest::newRow("end") << QDate(2023, 2, 28)
<< QList<QDate>() // no 'earlier this week'
<< QList<QDate> {QDate(2023, 2, 1), QDate(2023, 2, 26)};
QTest::newRow("edge") << QDate(2023, 3, 1)
<< QList<QDate> { QDate(2023, 2 , 27) }
<< QList<QDate>(); // no 'earlier this month'
QTest::newRow("edge2") << QDate(2023, 3, 2)
<< QList<QDate> { QDate(2023, 2 , 27), QDate(2023, 2 , 28) }
<< QList<QDate>(); // no 'earlier this month'
QTest::newRow("startWeekNotMonth") << QDate(2023, 5, 7)
<< QList<QDate> { QDate(2023, 5 , 1), QDate(2023, 5 , 2), QDate(2023, 5 , 3), QDate(2023, 5 , 4) , QDate(2023, 5 , 5) }
<< QList<QDate>(); // no 'earlier this month'
}
2022-12-13 20:07:04 +01:00
void TestWalletHistoryModel::dateSorting()
{
auto wallet = createWallet();
wallet->createTransactions1();
// The above created 6000 transactions, which is a tad much. We move the first 5989 to somewhere in the past.
for (int i = 1; i < 5990; ++i) {
wallet->setTransactionTime(i, 1760000000); // oct 2025
}
// we set a bunch of dates on the last 11 transactions.
wallet->setTransactionTime(6000, // 0
QDateTime(QDate(2026, 01, 26), QTime(14, 44)).toSecsSinceEpoch());
wallet->setTransactionTime(5999, // 1
QDateTime(QDate(2026, 01, 26), QTime(14, 28)).toSecsSinceEpoch());
wallet->setTransactionTime(5998, // 2
QDateTime(QDate(2026, 01, 25), QTime(23, 44)).toSecsSinceEpoch());
wallet->setTransactionTime(5997, // 3
QDateTime(QDate(2026, 01, 25), QTime(23, 36)).toSecsSinceEpoch());
wallet->setTransactionTime(5996, // 4
QDateTime(QDate(2026, 01, 25), QTime(22, 50)).toSecsSinceEpoch());
wallet->setTransactionTime(5995, // 5
QDateTime(QDate(2026, 01, 25), QTime(22, 48)).toSecsSinceEpoch());
wallet->setTransactionTime(5994, // 6
QDateTime(QDate(2026, 01, 23), QTime(19, 7)).toSecsSinceEpoch());
wallet->setTransactionTime(5993, // 7
QDateTime(QDate(2026, 01, 21), QTime(20, 28)).toSecsSinceEpoch());
wallet->setTransactionTime(5992, // 8
QDateTime(QDate(2026, 01, 20), QTime(13, 6)).toSecsSinceEpoch());
wallet->setTransactionTime(5991, 1769027280);
wallet->setTransactionTime(5990, 1769026820);
std::unique_ptr<MockWalletHistoryModel> model(new MockWalletHistoryModel(wallet));
model->setMockDate(QDate(2026, 01, 26));
QCOMPARE(model->rowCount(), 6000);
auto first = model->data(model->index(0, 0), WalletHistoryModel::MinedHeight);
QVERIFY(first.isValid());
QCOMPARE(first.toInt(), 6000);
first = model->data(model->index(0, 0), WalletHistoryModel::GroupId);
QVERIFY(first.isValid());
QCOMPARE(model->groupingPeriod(first.toInt()), "Today");
auto group = model->data(model->index(1, 0), WalletHistoryModel::GroupId);
QVERIFY(group.isValid());
QCOMPARE(model->groupingPeriod(group.toInt()), "Today");
group = model->data(model->index(2, 0), WalletHistoryModel::GroupId);
QVERIFY(group.isValid());
QCOMPARE(model->groupingPeriod(group.toInt()), "Yesterday");
group = model->data(model->index(3, 0), WalletHistoryModel::GroupId);
QVERIFY(group.isValid());
QCOMPARE(model->groupingPeriod(group.toInt()), "Yesterday");
group = model->data(model->index(4, 0), WalletHistoryModel::GroupId);
QVERIFY(group.isValid());
QCOMPARE(model->groupingPeriod(group.toInt()), "Yesterday");
group = model->data(model->index(5, 0), WalletHistoryModel::GroupId);
QVERIFY(group.isValid());
QCOMPARE(model->groupingPeriod(group.toInt()), "Yesterday");
group = model->data(model->index(6, 0), WalletHistoryModel::GroupId);
QVERIFY(group.isValid());
QCOMPARE(model->groupingPeriod(group.toInt()), "Earlier this month");
group = model->data(model->index(7, 0), WalletHistoryModel::GroupId);
QVERIFY(group.isValid());
QCOMPARE(model->groupingPeriod(group.toInt()), "Earlier this month");
group = model->data(model->index(8, 0), WalletHistoryModel::GroupId);
QVERIFY(group.isValid());
QCOMPARE(model->groupingPeriod(group.toInt()), "Earlier this month");
}
2022-12-13 20:07:04 +01:00
QTEST_MAIN(TestWalletHistoryModel)