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

test(FriendListManager): add contact management test

This commit is contained in:
bodwok 2022-01-09 20:52:42 +03:00 committed by Anthony Bilinski
parent 68ca7354be
commit 0a9e121811
No known key found for this signature in database
GPG Key ID: 2AA8E0DA1B31FB3C
8 changed files with 566 additions and 7 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,532 @@
/*
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) {}
bool isFriend() const { return true; }
bool isGroup() const { return false; }
bool isOnline() const { return online; }
bool widgetIsVisible() const { return visible; }
QString getNameItem() const { return name; }
QDateTime getLastActivity() const { return lastActivity; }
QWidget* getWidget() { return nullptr; }
void setWidgetVisible(bool v) { visible = v; }
private:
QString name;
QDateTime lastActivity;
bool online = false;
bool visible = true;
};
class MockGroup : public IFriendListItem
{
public:
MockGroup()
: name("group") {}
MockGroup(const QString& nameStr)
:name(nameStr) {}
bool isFriend() const { return false; }
bool isGroup() const { return true; }
bool isOnline() const { return true; }
bool widgetIsVisible() const { return visible; }
QString getNameItem() const { return name; }
QDateTime getLastActivity() const { return QDateTime::currentDateTime(); }
QWidget* getWidget() { return nullptr; }
void setWidgetVisible(bool v) { visible = v; }
private:
QString name;
bool visible = true;
};
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)) {
QWARN("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"