|
|
|
|
@ -1,5 +1,8 @@
|
|
|
|
|
/* Настоящие core/storage, Qt worker и кеш: два канала, публикация после COMMIT и restart. */ |
|
|
|
|
#include "../src/avatars/avatarmanager.h" |
|
|
|
|
#include "../src/avatars/avatarcrop.h" |
|
|
|
|
#include "../src/avatars/avatargallery.h" |
|
|
|
|
#include "../src/imageviewer_window.h" |
|
|
|
|
#include "../db/db_manager.h" |
|
|
|
|
#include "../transport/gui_bridge.h" |
|
|
|
|
#include <QtTest> |
|
|
|
|
@ -7,6 +10,8 @@
|
|
|
|
|
#include <QFile> |
|
|
|
|
#include <QCryptographicHash> |
|
|
|
|
#include <QPainter> |
|
|
|
|
#include <QDialog> |
|
|
|
|
#include <QPushButton> |
|
|
|
|
extern "C" { |
|
|
|
|
#include "utun_instance.h" |
|
|
|
|
#include "chat/chat_core.h" |
|
|
|
|
@ -99,6 +104,44 @@ private slots:
|
|
|
|
|
QVERIFY(!AvatarCache::prepare(input,directory.path(),QRectF(0.7,0,0.5,1)).error.isEmpty()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void exifRotationKeepsOriginalBytesAndSelectedArea() { |
|
|
|
|
QTemporaryDir directory; QVERIFY(directory.isValid()); |
|
|
|
|
QImage image(800,400,QImage::Format_RGB32); image.fill(Qt::blue); |
|
|
|
|
QPainter painter(&image); painter.fillRect(QRect(0,0,400,400),Qt::red); painter.end(); |
|
|
|
|
QByteArray jpeg; QBuffer buffer(&jpeg); QVERIFY(buffer.open(QIODevice::WriteOnly)); QVERIFY(image.save(&buffer,"JPEG",95)); |
|
|
|
|
const QByteArray exif=QByteArray::fromHex("ffe1002245786966000049492a0008000000010012010300010000000600000000000000"); |
|
|
|
|
const QByteArray original=jpeg.left(2)+exif+jpeg.mid(2); |
|
|
|
|
const QString path=directory.path()+"/rotated.jpg"; QFile file(path); QVERIFY(file.open(QIODevice::WriteOnly)); |
|
|
|
|
QCOMPARE(file.write(original),qint64(original.size())); file.close(); |
|
|
|
|
const auto prepared=AvatarCache::prepare(path,directory.path(),QRectF(0,0,1,0.5)); |
|
|
|
|
QVERIFY2(prepared.error.isEmpty(),qPrintable(prepared.error)); QCOMPARE(prepared.record.size,QSize(400,800)); |
|
|
|
|
const auto loaded=AvatarCache::load(directory.path()+'/'+prepared.hash+".json",prepared.hash); |
|
|
|
|
QVERIFY(loaded.image.pixelColor(128,128).red()>240); |
|
|
|
|
QFile stored(directory.path()+'/'+prepared.record.original); QVERIFY(stored.open(QIODevice::ReadOnly)); QCOMPARE(stored.readAll(),original); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void editorDragSelectsTheEdgeAndCancelDoesNotPrepareFiles() { |
|
|
|
|
QTemporaryDir directory; QVERIFY(directory.isValid()); |
|
|
|
|
QImage image(800,400,QImage::Format_RGB32); image.fill(Qt::blue); |
|
|
|
|
const QString source=directory.path()+"/source.png"; QVERIFY(image.save(source)); |
|
|
|
|
QTimer automate; automate.setInterval(10); |
|
|
|
|
connect(&automate,&QTimer::timeout,this,[] { |
|
|
|
|
auto* dialog=QApplication::activeModalWidget(); if (!dialog) return; |
|
|
|
|
auto* view=dialog->findChild<QWidget*>("avatarCropView"); auto* upload=dialog->findChild<QPushButton*>("avatarCropUpload"); |
|
|
|
|
if (!view || !upload || !upload->isEnabled()) return; |
|
|
|
|
const QPoint center=view->rect().center(); |
|
|
|
|
QTest::mousePress(view,Qt::LeftButton,Qt::NoModifier,center); |
|
|
|
|
QTest::mouseMove(view,center+QPoint(1000,0)); QTest::mouseRelease(view,Qt::LeftButton,Qt::NoModifier,center+QPoint(1000,0)); |
|
|
|
|
QTest::mouseClick(upload,Qt::LeftButton); |
|
|
|
|
}); |
|
|
|
|
automate.start(); QRectF crop; QVERIFY(selectAvatarCrop(source,crop,nullptr)); automate.stop(); |
|
|
|
|
QVERIFY(qAbs(crop.x())<0.001); QVERIFY(qAbs(crop.y())<0.001); |
|
|
|
|
QVERIFY(qAbs(crop.width()-0.5)<0.001); QVERIFY(qAbs(crop.height()-1)<0.001); |
|
|
|
|
QTimer::singleShot(10,[] { if (auto* dialog=qobject_cast<QDialog*>(QApplication::activeModalWidget())) dialog->reject(); }); |
|
|
|
|
QVERIFY(!selectAvatarCrop(source,crop,nullptr)); |
|
|
|
|
QCOMPARE(QDir(directory.path()).entryList({"*.json","*.webp"},QDir::Files).size(),0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void uploadReplicateCacheRestartAndRemove() { |
|
|
|
|
debug_config_init(); debug_set_level(DEBUG_LEVEL_INFO); |
|
|
|
|
debug_set_category_level(DEBUG_CATEGORY_CHAT_SYNC, DEBUG_LEVEL_DEBUG); |
|
|
|
|
@ -208,6 +251,17 @@ private slots:
|
|
|
|
|
QCOMPARE(manager.galleryImage(selected,true).size(),QSize(300,200)); |
|
|
|
|
QVERIFY(manager.galleryImage(selected,true).pixelColor(0,0).red()>240); |
|
|
|
|
manager.closeGallery(); |
|
|
|
|
showAvatarGallery(channels[0].channelId,testInstance->node_id); |
|
|
|
|
QDialog* gallery=nullptr; |
|
|
|
|
for (auto* widget : QApplication::topLevelWidgets()) if (widget->windowTitle()=="Avatars") gallery=qobject_cast<QDialog*>(widget); |
|
|
|
|
QVERIFY(gallery); auto* viewer=gallery->findChild<ImageViewerWindow*>(); QVERIFY(viewer); |
|
|
|
|
QTRY_VERIFY_WITH_TIMEOUT(viewer->grab().toImage().pixelColor(viewer->rect().center()).red()>240,5000); |
|
|
|
|
for (int i=0;i<5;i++) QVERIFY(gallery->findChild<QPushButton*>(QString("avatarPreview%1").arg(i))); |
|
|
|
|
QTRY_COMPARE_WITH_TIMEOUT(manager.gallery().size(),2,5000); |
|
|
|
|
auto* next=gallery->findChild<QPushButton*>(manager.gallery().indexOf(selected)==0 ? "avatarNext" : "avatarPrevious"); |
|
|
|
|
QVERIFY(next); QTest::mouseClick(next,Qt::LeftButton); |
|
|
|
|
QTRY_VERIFY_WITH_TIMEOUT(viewer->grab().toImage().pixelColor(viewer->rect().center()).blue()>240,5000); |
|
|
|
|
gallery->close(); QTRY_VERIFY_WITH_TIMEOUT(manager.gallery().isEmpty(),5000); |
|
|
|
|
manager.clearDefault(); |
|
|
|
|
for (const auto& channel : channels) { |
|
|
|
|
uint8_t wire[CHAT_MEMBER_DISPLAY_SIZE]; |
|
|
|
|
|