2026-08-03 22:58:30 +02:00
|
|
|
#include "Types.h"
|
2026-08-05 18:32:30 +02:00
|
|
|
#include "Metrics.h"
|
2026-08-03 22:58:30 +02:00
|
|
|
|
2026-08-05 18:32:30 +02:00
|
|
|
#include <QTemporaryDir>
|
2026-08-03 22:58:30 +02:00
|
|
|
#include <QTest>
|
|
|
|
|
|
|
|
|
|
using namespace Qt::StringLiterals;
|
|
|
|
|
|
|
|
|
|
class TypesTest final : public QObject {
|
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
|
|
private slots:
|
|
|
|
|
void parsesShareUrl();
|
|
|
|
|
void rejectsNonShareUrl();
|
|
|
|
|
void plansByChecksum();
|
2026-08-05 18:32:30 +02:00
|
|
|
void persistsStatisticsAcrossInstances();
|
2026-08-03 22:58:30 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void TypesTest::parsesShareUrl()
|
|
|
|
|
{
|
|
|
|
|
QString error;
|
|
|
|
|
const auto endpoint = ShareEndpoint::fromUserInput(
|
|
|
|
|
u"https://photos.example.test/immich/share/summer-2026?ignored=yes"_s, u"secret"_s, &error);
|
|
|
|
|
QCOMPARE(error, QString{});
|
|
|
|
|
QCOMPARE(endpoint.apiRoot, QUrl{u"https://photos.example.test/immich/api"_s});
|
|
|
|
|
QCOMPARE(endpoint.credential, u"summer-2026"_s);
|
|
|
|
|
QCOMPARE(endpoint.password, u"secret"_s);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TypesTest::rejectsNonShareUrl()
|
|
|
|
|
{
|
|
|
|
|
QString error;
|
|
|
|
|
const auto endpoint = ShareEndpoint::fromUserInput(u"file:///tmp/share/key"_s, {}, &error);
|
|
|
|
|
QVERIFY(!error.isEmpty());
|
|
|
|
|
QVERIFY(endpoint.apiRoot.isEmpty());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TypesTest::plansByChecksum()
|
|
|
|
|
{
|
|
|
|
|
ShareInfo left;
|
|
|
|
|
left.assets = {{u"1"_s, u"same"_s}, {u"2"_s, u"left-only"_s}, {u"3"_s, {}}};
|
|
|
|
|
ShareInfo right;
|
|
|
|
|
right.assets = {{u"4"_s, u"same"_s}, {u"5"_s, u"right-only"_s}};
|
|
|
|
|
|
|
|
|
|
const auto plan = buildSyncPlan(left, right);
|
|
|
|
|
QCOMPARE(plan.leftToRight.size(), 1);
|
|
|
|
|
QCOMPARE(plan.leftToRight.front().id, u"2"_s);
|
|
|
|
|
QCOMPARE(plan.rightToLeft.size(), 1);
|
|
|
|
|
QCOMPARE(plan.rightToLeft.front().id, u"5"_s);
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-05 18:32:30 +02:00
|
|
|
void TypesTest::persistsStatisticsAcrossInstances()
|
|
|
|
|
{
|
|
|
|
|
QTemporaryDir directory;
|
|
|
|
|
QVERIFY(directory.isValid());
|
|
|
|
|
const QString path = directory.filePath(u"stats.json"_s);
|
|
|
|
|
|
|
|
|
|
Metrics first{path};
|
|
|
|
|
first.synchronizationStarted();
|
|
|
|
|
first.assetFinished(u"IMAGE"_s, true, 1'024);
|
|
|
|
|
first.synchronizationFinished(true);
|
|
|
|
|
|
|
|
|
|
Metrics second{path};
|
|
|
|
|
second.assetFinished(u"VIDEO"_s, true, 2'048);
|
|
|
|
|
second.assetFinished(u"IMAGE"_s, false, 512);
|
|
|
|
|
|
|
|
|
|
const QJsonObject statistics = first.statistics();
|
|
|
|
|
QCOMPARE(statistics.value(u"syncs"_s).toInteger(), 1);
|
|
|
|
|
QCOMPARE(statistics.value(u"assets"_s).toInteger(), 2);
|
|
|
|
|
QCOMPARE(statistics.value(u"images"_s).toInteger(), 1);
|
|
|
|
|
QCOMPARE(statistics.value(u"videos"_s).toInteger(), 1);
|
|
|
|
|
QCOMPARE(statistics.value(u"other"_s).toInteger(), 0);
|
|
|
|
|
QCOMPARE(statistics.value(u"bytes"_s).toInteger(), 3'072);
|
|
|
|
|
QVERIFY(second.prometheus().contains("immich_sync_lifetime_synchronizations_total 1"));
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-03 22:58:30 +02:00
|
|
|
QTEST_MAIN(TypesTest)
|
|
|
|
|
#include "TypesTest.moc"
|