1
0
mirror of https://github.com/qTox/qTox.git synced 2024-03-22 14:00:36 +08:00

Merge pull request #6437

Anthony Bilinski (1):
      chore(cleanup): Minor cleanup to contact management test

bodwok (1):
      test(FriendListManager): add contact management test
This commit is contained in:
Anthony Bilinski 2022-02-17 17:42:14 -08:00
commit 0cb760dfa2
No known key found for this signature in database
GPG Key ID: 2AA8E0DA1B31FB3C
8 changed files with 574 additions and 7 deletions

View File

@ -53,6 +53,7 @@ auto_test(persistence offlinemsgengine "")
if(NOT "${SMILEYS}" STREQUAL "DISABLED")
auto_test(persistence smileypack "${${PROJECT_NAME}_RESOURCES}") # needs emojione
endif()
auto_test(model friendlistmanager "")
auto_test(model friendmessagedispatcher "")
auto_test(model groupmessagedispatcher "${MOCK_SOURCES}")
auto_test(model messageprocessor "")

View File

@ -42,7 +42,7 @@ bool FriendListManager::getPositionsChanged() const
void FriendListManager::addFriendListItem(IFriendListItem *item)
{
if (item->isGroup()) {
if (item->isGroup() && item->getWidget() != nullptr) {
items.push_back(IFriendListItemPtr(item, [](IFriendListItem* groupItem){
groupItem->getWidget()->deleteLater();}));
} else {
@ -102,24 +102,24 @@ void FriendListManager::applyFilter()
for (IFriendListItemPtr itemTmp : items) {
if (searchString.isEmpty()) {
itemTmp->getWidget()->setVisible(true);
itemTmp->setWidgetVisible(true);
} else {
QString tmp_name = itemTmp->getNameItem();
itemTmp->getWidget()->setVisible(tmp_name.contains(searchString, Qt::CaseInsensitive));
itemTmp->setWidgetVisible(tmp_name.contains(searchString, Qt::CaseInsensitive));
}
if (filterParams.hideOnline && itemTmp->isOnline()) {
if (itemTmp->isFriend()) {
itemTmp->getWidget()->setVisible(false);
itemTmp->setWidgetVisible(false);
}
}
if (filterParams.hideOffline && !itemTmp->isOnline()) {
itemTmp->getWidget()->setVisible(false);
itemTmp->setWidgetVisible(false);
}
if (filterParams.hideGroups && itemTmp->isGroup()) {
itemTmp->getWidget()->setVisible(false);
itemTmp->setWidgetVisible(false);
}
}
@ -144,7 +144,7 @@ void FriendListManager::updatePositions()
return;
}
}
std::sort(items.begin(), items.end(),sortName);
std::sort(items.begin(), items.end(), sortName);
} else {
auto sortActivity = [&](const IFriendListItemPtr &a, const IFriendListItemPtr &b) {

View File

@ -36,9 +36,11 @@ public:
virtual bool isFriend() const = 0;
virtual bool isGroup() const = 0;
virtual bool isOnline() const = 0;
virtual bool widgetIsVisible() const = 0;
virtual QString getNameItem() const = 0;
virtual QDateTime getLastActivity() const = 0;
virtual QWidget* getWidget() = 0;
virtual void setWidgetVisible(bool) = 0;
virtual int getCircleId() const
{

View File

@ -370,6 +370,11 @@ bool FriendWidget::isOnline() const
return Status::isOnline(frnd->getStatus());
}
bool FriendWidget::widgetIsVisible() const
{
return isVisible();
}
QString FriendWidget::getNameItem() const
{
return nameLabel->fullText();
@ -386,6 +391,11 @@ QWidget *FriendWidget::getWidget()
return this;
}
void FriendWidget::setWidgetVisible(bool visible)
{
setVisible(visible);
}
int FriendWidget::getCircleId() const
{
return chatroom->getCircleId();

View File

@ -48,10 +48,12 @@ public:
bool isFriend() const final;
bool isGroup() const final;
bool isOnline() const final;
bool widgetIsVisible() const final;
QString getNameItem() const final;
QDateTime getLastActivity() const final;
int getCircleId() const final;
QWidget* getWidget() final;
void setWidgetVisible(bool visible) final;
signals:
void friendWidgetClicked(FriendWidget* widget);

View File

@ -209,6 +209,11 @@ bool GroupWidget::isOnline() const
return true;
}
bool GroupWidget::widgetIsVisible() const
{
return isVisible();
}
QDateTime GroupWidget::getLastActivity() const
{
return QDateTime::currentDateTime();
@ -219,6 +224,11 @@ QWidget *GroupWidget::getWidget()
return this;
}
void GroupWidget::setWidgetVisible(bool visible)
{
setVisible(visible);
}
// TODO: Remove
Group* GroupWidget::getGroup() const
{

View File

@ -47,8 +47,10 @@ public:
bool isGroup() const final;
QString getNameItem() const final;
bool isOnline() const final;
bool widgetIsVisible() const final;
QDateTime getLastActivity() const final;
QWidget* getWidget() final;
void setWidgetVisible(bool visible) final;
signals:
void groupWidgetClicked(GroupWidget* widget);

View File

@ -0,0 +1,540 @@
/*
Copyright © 2022 by The qTox Project Contributors
This file is part of qTox, a Qt-based graphical interface for Tox.
qTox is libre 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.
qTox 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 qTox. If not, see <http://www.gnu.org/licenses/>.
*/
#include "src/model/friendlist/friendlistmanager.h"
#include <QTest>
#include <QSignalSpy>
class MockFriend : public IFriendListItem
{
public:
MockFriend()
: name("No Name"),
lastActivity(QDateTime::currentDateTime()),
online(false) {}
MockFriend(const QString& nameStr, bool onlineRes, const QDateTime& lastAct)
: name(nameStr),
lastActivity(lastAct),
online(onlineRes) {}
~MockFriend();
bool isFriend() const override { return true; }
bool isGroup() const override { return false; }
bool isOnline() const override { return online; }
bool widgetIsVisible() const override { return visible; }
QString getNameItem() const override { return name; }
QDateTime getLastActivity() const override { return lastActivity; }
QWidget* getWidget() override { return nullptr; }
void setWidgetVisible(bool v) override { visible = v; }
private:
QString name;
QDateTime lastActivity;
bool online = false;
bool visible = true;
};
MockFriend::~MockFriend() = default;
class MockGroup : public IFriendListItem
{
public:
MockGroup()
: name("group") {}
MockGroup(const QString& nameStr)
:name(nameStr) {}
~MockGroup();
bool isFriend() const override { return false; }
bool isGroup() const override { return true; }
bool isOnline() const override { return true; }
bool widgetIsVisible() const override { return visible; }
QString getNameItem() const override { return name; }
QDateTime getLastActivity() const override { return QDateTime::currentDateTime(); }
QWidget* getWidget() override { return nullptr; }
void setWidgetVisible(bool v) override { visible = v; }
private:
QString name;
bool visible = true;
};
MockGroup::~MockGroup() = default;
class FriendItemsBuilder
{
public:
FriendItemsBuilder* addOfflineFriends()
{
QStringList testNames {".test", "123", "A test user", "Aatest user", "atest",
"btest", "ctest", "Test user", "user with long nickname one",
"user with long nickname two"};
for (int i = 0; i < testNames.size(); ++i) {
int unsortedIndex = i % 2 ? i - 1 : testNames.size() - i - 1; // Mixes positions
int sortedByActivityIndex = testNames.size() - i - 1;
unsortedAllFriends.append(testNames[unsortedIndex]);
sortedByNameOfflineFriends.append(testNames[i]);
sortedByActivityFriends.append(testNames[sortedByActivityIndex]);
}
return this;
}
FriendItemsBuilder* addOnlineFriends()
{
QStringList testNames {".test online", "123 online", "A test user online",
"Aatest user online", "atest online", "btest online", "ctest online",
"Test user online", "user with long nickname one online",
"user with long nickname two online"};
for (int i = 0; i < testNames.size(); ++i) {
int unsortedIndex = i % 2 ? i - 1 : testNames.size() - i - 1;
int sortedByActivityIndex = testNames.size() - i - 1;
unsortedAllFriends.append(testNames[unsortedIndex]);
sortedByNameOnlineFriends.append(testNames[i]);
sortedByActivityFriends.append(testNames[sortedByActivityIndex]);
}
return this;
}
FriendItemsBuilder* addGroups()
{
unsortedGroups.append("Test Group");
unsortedGroups.append("A Group");
unsortedGroups.append("Test Group long name");
unsortedGroups.append("Test Group long aname");
unsortedGroups.append("123");
sortedByNameGroups.push_back("123");
sortedByNameGroups.push_back("A Group");
sortedByNameGroups.push_back("Test Group");
sortedByNameGroups.push_back("Test Group long aname");
sortedByNameGroups.push_back("Test Group long name");
return this;
}
FriendItemsBuilder* setGroupsOnTop(bool val)
{
groupsOnTop = val;
return this;
}
/**
* @brief buildUnsorted Creates items to init the FriendListManager.
* FriendListManager will own and manage these items
* @return Unsorted vector of items
*/
QVector<IFriendListItem*> buildUnsorted()
{
checkDifferentNames();
QVector<IFriendListItem*> vec;
for (auto name : unsortedAllFriends) {
vec.push_back(new MockFriend(name, isOnline(name), getDateTime(name)));
}
for (auto name : unsortedGroups) {
vec.push_back(new MockGroup(name));
}
clear();
return vec;
}
/**
* @brief buildSortedByName Create items to compare with items
* from the FriendListManager. FriendItemsBuilder owns these items
* @return Sorted by name vector of items
*/
QVector<std::shared_ptr<IFriendListItem>> buildSortedByName()
{
QVector<std::shared_ptr<IFriendListItem>> vec;
if (!groupsOnTop) {
for (auto name : sortedByNameOnlineFriends) {
vec.push_back(std::shared_ptr<IFriendListItem>(new MockFriend(name, true, QDateTime::currentDateTime())));
}
for (auto name : sortedByNameGroups) {
vec.push_back(std::shared_ptr<IFriendListItem>(new MockGroup(name)));
}
} else {
for (auto name : sortedByNameGroups) {
vec.push_back(std::shared_ptr<IFriendListItem>(new MockGroup(name)));
}
for (auto name : sortedByNameOnlineFriends) {
vec.push_back(std::shared_ptr<IFriendListItem>(new MockFriend(name, true, QDateTime::currentDateTime())));
}
}
for (auto name : sortedByNameOfflineFriends) {
vec.push_back(std::shared_ptr<IFriendListItem>(new MockFriend(name, false, getDateTime(name))));
}
clear();
return vec;
}
/**
* @brief buildSortedByActivity Creates items to compare with items
* from FriendListManager. FriendItemsBuilder owns these items
* @return Sorted by activity vector of items
*/
QVector<std::shared_ptr<IFriendListItem>> buildSortedByActivity()
{
QVector<std::shared_ptr<IFriendListItem>> vec;
// Add groups on top
for (auto name : sortedByNameGroups) {
vec.push_back(std::shared_ptr<IFriendListItem>(new MockGroup(name)));
}
// Add friends and set the date of the last activity by index
QDateTime dateTime = QDateTime::currentDateTime();
for (int i = 0; i < sortedByActivityFriends.size(); ++i) {
QString name = sortedByActivityFriends.at(i);
vec.push_back(std::shared_ptr<IFriendListItem>(new MockFriend(name, isOnline(name), getDateTime(name))));
}
clear();
return vec;
}
private:
void clear()
{
sortedByNameOfflineFriends.clear();
sortedByNameOnlineFriends.clear();
sortedByNameGroups.clear();
sortedByActivityFriends.clear();
sortedByActivityGroups.clear();
unsortedAllFriends.clear();
unsortedGroups.clear();
groupsOnTop = true;
}
bool isOnline(const QString& name)
{
return sortedByNameOnlineFriends.indexOf(name) != -1;
}
/**
* @brief checkDifferentNames The check is necessary for
* the correct setting of the online status
*/
void checkDifferentNames() {
for (auto name : sortedByNameOnlineFriends) {
if (sortedByNameOfflineFriends.contains(name, Qt::CaseInsensitive)) {
QFAIL("Names in sortedByNameOnlineFriends and sortedByNameOfflineFriends "
"should be different");
break;
}
}
}
QDateTime getDateTime(const QString& name)
{
QDateTime dateTime = QDateTime::currentDateTime();
int pos = sortedByActivityFriends.indexOf(name);
if (pos == -1) {
return dateTime;
}
const int dayRatio = -1;
return dateTime.addDays(dayRatio * pos * pos);
}
QStringList sortedByNameOfflineFriends;
QStringList sortedByNameOnlineFriends;
QStringList sortedByNameGroups;
QStringList sortedByActivityFriends;
QStringList sortedByActivityGroups;
QStringList unsortedAllFriends;
QStringList unsortedGroups;
bool groupsOnTop = true;
};
class TestFriendListManager : public QObject
{
Q_OBJECT
private slots:
void testAddFriendListItem();
void testSortByName();
void testSortByActivity();
void testSetFilter();
void testApplyFilterSearchString();
void testApplyFilterByStatus();
void testSetGroupsOnTop();
private:
std::unique_ptr<FriendListManager> createManagerWithItems(
const QVector<IFriendListItem*> itemsVec);
};
void TestFriendListManager::testAddFriendListItem()
{
auto manager = std::unique_ptr<FriendListManager>(new FriendListManager(0, this));
QSignalSpy spy(manager.get(), &FriendListManager::itemsChanged);
FriendItemsBuilder listBuilder;
auto checkFunc = [&](const QVector<IFriendListItem*> itemsVec) {
for (auto item : itemsVec) {
manager->addFriendListItem(item);
}
QCOMPARE(manager->getItems().size(), itemsVec.size());
QCOMPARE(spy.count(), itemsVec.size());
spy.clear();
for (auto item : itemsVec) {
manager->removeFriendListItem(item);
}
QCOMPARE(manager->getItems().size(), 0);
QCOMPARE(spy.count(), itemsVec.size());
spy.clear();
};
// Only friends
checkFunc(listBuilder.addOfflineFriends()->buildUnsorted());
checkFunc(listBuilder.addOfflineFriends()->addOnlineFriends()->buildUnsorted());
// Friends and groups
checkFunc(listBuilder.addOfflineFriends()->addGroups()->buildUnsorted());
checkFunc(listBuilder.addOfflineFriends()->addOnlineFriends()->addGroups()->buildUnsorted());
// Only groups
checkFunc(listBuilder.addGroups()->buildUnsorted());
}
void TestFriendListManager::testSortByName()
{
FriendItemsBuilder listBuilder;
auto unsortedVec = listBuilder.addOfflineFriends()
->addOnlineFriends()->addGroups()->buildUnsorted();
auto sortedVec = listBuilder.addOfflineFriends()
->addOnlineFriends()->addGroups()->buildSortedByName();
auto manager = createManagerWithItems(unsortedVec);
manager->sortByName();
bool success = manager->getPositionsChanged();
manager->sortByName();
QCOMPARE(success, true);
QCOMPARE(manager->getPositionsChanged(), false);
QCOMPARE(manager->getItems().size(), sortedVec.size());
for (int i = 0; i < sortedVec.size(); ++i) {
IFriendListItem* fromManager = manager->getItems().at(i).get();
std::shared_ptr<IFriendListItem> fromSortedVec = sortedVec.at(i);
QCOMPARE(fromManager->getNameItem(), fromSortedVec->getNameItem());
}
}
void TestFriendListManager::testSortByActivity()
{
FriendItemsBuilder listBuilder;
auto unsortedVec = listBuilder.addOfflineFriends()
->addOnlineFriends()->addGroups()->buildUnsorted();
auto sortedVec = listBuilder.addOfflineFriends()
->addOnlineFriends()->addGroups()->buildSortedByActivity();
std::unique_ptr<FriendListManager> manager = createManagerWithItems(unsortedVec);
manager->sortByActivity();
bool success = manager->getPositionsChanged();
manager->sortByActivity();
QCOMPARE(success, true);
QCOMPARE(manager->getPositionsChanged(), false);
QCOMPARE(manager->getItems().size(), sortedVec.size());
for (int i = 0; i < sortedVec.size(); ++i) {
auto fromManager = manager->getItems().at(i).get();
auto fromSortedVec = sortedVec.at(i);
QCOMPARE(fromManager->getNameItem(), fromSortedVec->getNameItem());
}
}
void TestFriendListManager::testSetFilter()
{
FriendItemsBuilder listBuilder;
auto manager = createManagerWithItems(
listBuilder.addOfflineFriends()->addOnlineFriends()->addGroups()->buildUnsorted());
QSignalSpy spy(manager.get(), &FriendListManager::itemsChanged);
manager->setFilter("", false, false, false);
QCOMPARE(spy.count(), 0);
manager->setFilter("Test", true, false, false);
manager->setFilter("Test", true, false, false);
QCOMPARE(spy.count(), 1);
}
void TestFriendListManager::testApplyFilterSearchString()
{
FriendItemsBuilder listBuilder;
auto manager = createManagerWithItems(
listBuilder.addOfflineFriends()->addOnlineFriends()->addGroups()->buildUnsorted());
QVector<std::shared_ptr<IFriendListItem>> resultVec;
QString testNameA = "NOITEMSWITHTHISNAME";
QString testNameB = "Test Name B";
manager->sortByName();
manager->setFilter(testNameA, false, false, false);
manager->applyFilter();
resultVec = manager->getItems();
for (auto item : resultVec) {
QCOMPARE(item->widgetIsVisible(), false);
}
manager->sortByActivity();
manager->addFriendListItem(new MockFriend(testNameB, true, QDateTime::currentDateTime()));
manager->applyFilter();
resultVec = manager->getItems();
for (auto item : resultVec) {
QCOMPARE(item->widgetIsVisible(), false);
}
manager->addFriendListItem(new MockFriend(testNameA, true, QDateTime::currentDateTime()));
manager->applyFilter();
resultVec = manager->getItems();
for (auto item : resultVec) {
if (item->getNameItem() == testNameA) {
QCOMPARE(item->widgetIsVisible(), true);
} else {
QCOMPARE(item->widgetIsVisible(), false);
}
}
manager->setFilter("", false, false, false);
manager->applyFilter();
resultVec = manager->getItems();
for (auto item : resultVec) {
QCOMPARE(item->widgetIsVisible(), true);
}
}
void TestFriendListManager::testApplyFilterByStatus()
{
FriendItemsBuilder listBuilder;
auto manager = createManagerWithItems(
listBuilder.addOfflineFriends()->addOnlineFriends()->addGroups()->buildUnsorted());
auto onlineItems = listBuilder.addOnlineFriends()->buildSortedByName();
auto offlineItems = listBuilder.addOfflineFriends()->buildSortedByName();
auto groupItems = listBuilder.addGroups()->buildSortedByName();
manager->sortByName();
manager->setFilter("", true /*hideOnline*/, false /*hideOffline*/, false /*hideGroups*/);
manager->applyFilter();
for (auto item : manager->getItems()) {
if (item->isOnline() && item->isFriend()) {
QCOMPARE(item->widgetIsVisible(), false);
} else {
QCOMPARE(item->widgetIsVisible(), true);
}
}
manager->setFilter("", false /*hideOnline*/, true /*hideOffline*/, false /*hideGroups*/);
manager->applyFilter();
for (auto item : manager->getItems()) {
if (item->isOnline()) {
QCOMPARE(item->widgetIsVisible(), true);
} else {
QCOMPARE(item->widgetIsVisible(), false);
}
}
manager->setFilter("", false /*hideOnline*/, false /*hideOffline*/, true /*hideGroups*/);
manager->applyFilter();
for (auto item : manager->getItems()) {
if (item->isGroup()) {
QCOMPARE(item->widgetIsVisible(), false);
} else {
QCOMPARE(item->widgetIsVisible(), true);
}
}
manager->setFilter("", true /*hideOnline*/, true /*hideOffline*/, true /*hideGroups*/);
manager->applyFilter();
for (auto item : manager->getItems()) {
QCOMPARE(item->widgetIsVisible(), false);
}
manager->setFilter("", false /*hideOnline*/, false /*hideOffline*/, false /*hideGroups*/);
manager->applyFilter();
for (auto item : manager->getItems()) {
QCOMPARE(item->widgetIsVisible(), true);
}
}
void TestFriendListManager::testSetGroupsOnTop()
{
FriendItemsBuilder listBuilder;
auto manager = createManagerWithItems(
listBuilder.addOfflineFriends()->addOnlineFriends()->addGroups()->buildUnsorted());
auto sortedVecOnlineOnTop = listBuilder.addOfflineFriends()->addOnlineFriends()->addGroups()
->setGroupsOnTop(false)->buildSortedByName();
auto sortedVecGroupsOnTop = listBuilder.addOfflineFriends()->addOnlineFriends()->addGroups()
->setGroupsOnTop(true)->buildSortedByName();
manager->setGroupsOnTop(false);
manager->sortByName();
for (int i = 0; i < manager->getItems().size(); ++i) {
auto fromManager = manager->getItems().at(i);
auto fromSortedVec = sortedVecOnlineOnTop.at(i);
QCOMPARE(fromManager->getNameItem(), fromSortedVec->getNameItem());
}
manager->setGroupsOnTop(true);
manager->sortByName();
for (int i = 0; i < manager->getItems().size(); ++i) {
auto fromManager = manager->getItems().at(i);
auto fromSortedVec = sortedVecGroupsOnTop.at(i);
QCOMPARE(fromManager->getNameItem(), fromSortedVec->getNameItem());
}
}
std::unique_ptr<FriendListManager> TestFriendListManager::createManagerWithItems(
const QVector<IFriendListItem*> itemsVec)
{
std::unique_ptr<FriendListManager> manager =
std::unique_ptr<FriendListManager>(new FriendListManager(0, this));
for (auto item : itemsVec) {
manager->addFriendListItem(item);
}
return manager;
}
QTEST_GUILESS_MAIN(TestFriendListManager);
#include "friendlistmanager_test.moc"