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);
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-08 10:28:04 +02:00
|
|
|
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);
|
2023-05-08 10:28:04 +02:00
|
|
|
// 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.
|
2023-05-08 10:28:04 +02:00
|
|
|
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
|
|
|
}
|
2023-05-08 10:28:04 +02: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()
|
|
|
|
|
{
|
2023-05-08 10:28:04 +02:00
|
|
|
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));
|
2023-05-08 10:28:04 +02:00
|
|
|
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());
|
|
|
|
|
/*
|
2023-05-08 10:28:04 +02:00
|
|
|
* 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:
|
|
|
|
|
*
|
2023-05-08 10:28:04 +02:00
|
|
|
* 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");
|
|
|
|
|
|
2023-05-08 10:28:04 +02:00
|
|
|
#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
|
|
|
|
2023-05-08 10:28:04 +02: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");
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-08 10:28:04 +02:00
|
|
|
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");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-08 10:28:04 +02:00
|
|
|
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
|
|
|
|
2023-05-08 10:28:04 +02: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
|
|
|
|
2026-01-27 23:05:05 +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)
|