mirror of
https://github.com/qTox/qTox.git
synced 2024-03-22 14:00:36 +08:00
feat(notification): Notification string generator for multiple messages
This commit is contained in:
parent
14571abaa3
commit
a9f6543e43
|
@ -369,6 +369,8 @@ set(${PROJECT_NAME}_SOURCES
|
|||
src/model/chathistory.cpp
|
||||
src/model/toxclientstandards.h
|
||||
src/model/ibootstraplistgenerator.h
|
||||
src/model/notificationgenerator.h
|
||||
src/model/notificationgenerator.cpp
|
||||
src/net/bootstrapnodeupdater.cpp
|
||||
src/net/bootstrapnodeupdater.h
|
||||
src/net/avatarbroadcaster.cpp
|
||||
|
|
|
@ -48,6 +48,7 @@ auto_test(model groupmessagedispatcher)
|
|||
auto_test(model messageprocessor)
|
||||
auto_test(model sessionchatlog)
|
||||
auto_test(model exiftransform)
|
||||
auto_test(model notificationgenerator)
|
||||
|
||||
if (UNIX)
|
||||
auto_test(platform posixsignalnotifier)
|
||||
|
|
11
src/model/notificationdata.h
Normal file
11
src/model/notificationdata.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
#include <QPixmap>
|
||||
|
||||
struct NotificationData
|
||||
{
|
||||
QString title;
|
||||
QString message;
|
||||
QPixmap pixmap;
|
||||
};
|
247
src/model/notificationgenerator.cpp
Normal file
247
src/model/notificationgenerator.cpp
Normal file
|
@ -0,0 +1,247 @@
|
|||
#include "notificationgenerator.h"
|
||||
#include "src/chatlog/content/filetransferwidget.h"
|
||||
|
||||
#include <QCollator>
|
||||
|
||||
namespace
|
||||
{
|
||||
size_t getNumMessages(
|
||||
const QHash<const Friend*, size_t>& friendNotifications,
|
||||
const QHash<const Group* , size_t>& groupNotifications)
|
||||
{
|
||||
auto numMessages = std::accumulate(friendNotifications.begin(), friendNotifications.end(), 0);
|
||||
numMessages = std::accumulate(groupNotifications.begin(), groupNotifications.end(), numMessages);
|
||||
|
||||
return numMessages;
|
||||
}
|
||||
|
||||
size_t getNumChats(
|
||||
const QHash<const Friend*, size_t>& friendNotifications,
|
||||
const QHash<const Group* , size_t>& groupNotifications)
|
||||
{
|
||||
return friendNotifications.size() + groupNotifications.size();
|
||||
}
|
||||
|
||||
QString generateMultiChatTitle(size_t numChats, size_t numMessages)
|
||||
{
|
||||
// FIXME: how do I tr this
|
||||
return QObject::tr("%1 messages from %2 chats")
|
||||
.arg(numMessages)
|
||||
.arg(numChats);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
QString generateSingleChatTitle(
|
||||
const QHash<T, size_t> numNotifications,
|
||||
T contact)
|
||||
{
|
||||
if (numNotifications[contact] > 1)
|
||||
{
|
||||
return QObject::tr("%1 messages from %2")
|
||||
.arg(numNotifications[contact])
|
||||
.arg(contact->getDisplayedName());
|
||||
}
|
||||
else
|
||||
{
|
||||
return QObject::tr("%1")
|
||||
.arg(contact->getDisplayedName());
|
||||
}
|
||||
}
|
||||
|
||||
QString generateTitle(
|
||||
const QHash<const Friend*, size_t>& friendNotifications,
|
||||
const QHash<const Group* , size_t>& groupNotifications,
|
||||
const Friend* f)
|
||||
{
|
||||
auto numChats = getNumChats(friendNotifications, groupNotifications);
|
||||
if (numChats > 1)
|
||||
{
|
||||
return generateMultiChatTitle(numChats, getNumMessages(friendNotifications, groupNotifications));
|
||||
}
|
||||
else
|
||||
{
|
||||
return generateSingleChatTitle(friendNotifications, f);
|
||||
}
|
||||
}
|
||||
|
||||
QString generateTitle(
|
||||
const QHash<const Friend*, size_t>& friendNotifications,
|
||||
const QHash<const Group* , size_t>& groupNotifications,
|
||||
const Group* g)
|
||||
{
|
||||
auto numChats = getNumChats(friendNotifications, groupNotifications);
|
||||
if (numChats > 1)
|
||||
{
|
||||
return generateMultiChatTitle(numChats, getNumMessages(friendNotifications, groupNotifications));
|
||||
}
|
||||
else
|
||||
{
|
||||
return generateSingleChatTitle(groupNotifications, g);
|
||||
}
|
||||
}
|
||||
|
||||
QString generateContent(
|
||||
const QHash<const Friend*, size_t>& friendNotifications,
|
||||
const QHash<const Group*, size_t>& groupNotifications,
|
||||
QString lastMessage,
|
||||
const ToxPk& sender)
|
||||
{
|
||||
assert(friendNotifications.size() > 0 || groupNotifications.size() > 0);
|
||||
|
||||
auto numChats = getNumChats(friendNotifications, groupNotifications);
|
||||
if (numChats > 1) {
|
||||
// Copy all names into a vector to simplify formatting logic between
|
||||
// multiple lists
|
||||
std::vector<QString> displayNames;
|
||||
displayNames.reserve(numChats);
|
||||
|
||||
for (auto it = friendNotifications.begin(); it != friendNotifications.end(); ++it) {
|
||||
displayNames.push_back(it.key()->getDisplayedName());
|
||||
}
|
||||
|
||||
for (auto it = groupNotifications.begin(); it != groupNotifications.end(); ++it) {
|
||||
displayNames.push_back(it.key()->getDisplayedName());
|
||||
}
|
||||
|
||||
assert(displayNames.size() > 0);
|
||||
|
||||
// Lexiographically sort all display names to ensure consistent formatting
|
||||
QCollator collator;
|
||||
std::sort(displayNames.begin(), displayNames.end(), [&] (const QString& a, const QString& b) {
|
||||
return collator.compare(a, b) < 1;
|
||||
});
|
||||
|
||||
auto it = displayNames.begin();
|
||||
|
||||
QString ret = *it;
|
||||
|
||||
while (++it != displayNames.end()) {
|
||||
ret += ", " + *it;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
else {
|
||||
if (groupNotifications.size() == 1) {
|
||||
return groupNotifications.begin().key()->getPeerList()[sender] + ": " + lastMessage;
|
||||
}
|
||||
|
||||
return lastMessage;
|
||||
}
|
||||
}
|
||||
|
||||
QPixmap getSenderAvatar(Profile* profile, const ToxPk& sender)
|
||||
{
|
||||
return profile ? profile->loadAvatar(sender) : QPixmap();
|
||||
}
|
||||
} // namespace
|
||||
|
||||
NotificationGenerator::NotificationGenerator(
|
||||
INotificationSettings const& notificationSettings,
|
||||
Profile* profile)
|
||||
: notificationSettings(notificationSettings)
|
||||
, profile(profile)
|
||||
{}
|
||||
|
||||
NotificationData NotificationGenerator::friendMessageNotification(const Friend* f, const QString& message)
|
||||
{
|
||||
friendNotifications[f]++;
|
||||
|
||||
NotificationData ret;
|
||||
|
||||
if (notificationSettings.getNotifyHide()) {
|
||||
ret.title = tr("New message");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret.title = generateTitle(friendNotifications, groupNotifications, f);
|
||||
ret.message = generateContent(friendNotifications, groupNotifications, message, f->getPublicKey());
|
||||
ret.pixmap = getSenderAvatar(profile, f->getPublicKey());
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
NotificationData NotificationGenerator::groupMessageNotification(const Group* g, const ToxPk& sender, const QString& message)
|
||||
{
|
||||
groupNotifications[g]++;
|
||||
|
||||
NotificationData ret;
|
||||
|
||||
if (notificationSettings.getNotifyHide()){
|
||||
ret.title = tr("New group message");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret.title = generateTitle(friendNotifications, groupNotifications, g);
|
||||
ret.message = generateContent(friendNotifications, groupNotifications, message, sender);
|
||||
ret.pixmap = getSenderAvatar(profile, sender);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
NotificationData NotificationGenerator::fileTransferNotification(const Friend* f, const QString& filename, size_t fileSize)
|
||||
{
|
||||
friendNotifications[f]++;
|
||||
|
||||
NotificationData ret;
|
||||
|
||||
if (notificationSettings.getNotifyHide()) {
|
||||
ret.title = tr("Incoming file transfer");
|
||||
return ret;
|
||||
}
|
||||
|
||||
auto numChats = getNumChats(friendNotifications, groupNotifications);
|
||||
auto numMessages = getNumMessages(friendNotifications, groupNotifications);
|
||||
|
||||
if (numChats > 1 || numMessages > 1)
|
||||
{
|
||||
ret.title = generateTitle(friendNotifications, groupNotifications, f);
|
||||
ret.message = generateContent(friendNotifications, groupNotifications, tr("Incoming file transfer"), f->getPublicKey());
|
||||
}
|
||||
else
|
||||
{
|
||||
ret.title = f->getDisplayedName() + " - " + tr("File sent");
|
||||
ret.message = filename + " (" + FileTransferWidget::getHumanReadableSize(fileSize) + ")";
|
||||
}
|
||||
|
||||
ret.pixmap = getSenderAvatar(profile, f->getPublicKey());
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
NotificationData NotificationGenerator::groupInvitationNotification(const Friend* from)
|
||||
{
|
||||
NotificationData ret;
|
||||
|
||||
if (notificationSettings.getNotifyHide()) {
|
||||
ret.title = tr("Group invite received");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret.title = from->getDisplayedName() + tr(" invites you to join a group.");
|
||||
ret.message = "";
|
||||
ret.pixmap = getSenderAvatar(profile, from->getPublicKey());
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
NotificationData NotificationGenerator::friendRequestNotification(const ToxPk& sender, const QString& message)
|
||||
{
|
||||
NotificationData ret;
|
||||
|
||||
if (notificationSettings.getNotifyHide()) {
|
||||
ret.title = tr("Friend request received");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret.title = sender.toString() + tr(" sent you a friend request.");
|
||||
ret.message = message;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void NotificationGenerator::onNotificationActivated()
|
||||
{
|
||||
friendNotifications = {};
|
||||
groupNotifications = {};
|
||||
}
|
38
src/model/notificationgenerator.h
Normal file
38
src/model/notificationgenerator.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
#pragma once
|
||||
|
||||
|
||||
#include "notificationdata.h"
|
||||
#include "friend.h"
|
||||
#include "group.h"
|
||||
|
||||
#include "src/persistence/inotificationsettings.h"
|
||||
#include "src/persistence/profile.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QHash>
|
||||
|
||||
class NotificationGenerator : public QObject
|
||||
{
|
||||
public:
|
||||
NotificationGenerator(
|
||||
INotificationSettings const& notificationSettings,
|
||||
// Optional profile input to lookup avatars. Avatar lookup is not
|
||||
// currently mockable so we allow profile to be nullptr for unit
|
||||
// testing
|
||||
Profile* profile);
|
||||
|
||||
NotificationData friendMessageNotification(const Friend* f, const QString& message);
|
||||
NotificationData groupMessageNotification(const Group* g, const ToxPk& sender, const QString& message);
|
||||
NotificationData fileTransferNotification(const Friend* f, const QString& filename, size_t fileSize);
|
||||
NotificationData groupInvitationNotification(const Friend* from);
|
||||
NotificationData friendRequestNotification(const ToxPk& sender, const QString& message);
|
||||
|
||||
public slots:
|
||||
void onNotificationActivated();
|
||||
|
||||
private:
|
||||
INotificationSettings const& notificationSettings;
|
||||
Profile* profile;
|
||||
QHash<const Friend*, size_t> friendNotifications;
|
||||
QHash<const Group*, size_t> groupNotifications;
|
||||
};
|
|
@ -27,6 +27,4 @@ public:
|
|||
virtual ~IGroupSettings() = default;
|
||||
virtual QStringList getBlackList() const = 0;
|
||||
virtual void setBlackList(const QStringList& blist) = 0;
|
||||
virtual bool getGroupAlwaysNotify() const = 0;
|
||||
virtual void setGroupAlwaysNotify(bool newValue) = 0;
|
||||
};
|
||||
|
|
50
src/persistence/inotificationsettings.h
Normal file
50
src/persistence/inotificationsettings.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
Copyright © 2014-2019 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/>.
|
||||
*/
|
||||
|
||||
#ifndef INOTIFICATION_SETTINGS_H
|
||||
#define INOTIFICATION_SETTINGS_H
|
||||
|
||||
#include <QStringList>
|
||||
|
||||
class INotificationSettings
|
||||
{
|
||||
public:
|
||||
virtual bool getNotify() const = 0;
|
||||
virtual void setNotify(bool newValue) = 0;
|
||||
|
||||
virtual bool getShowWindow() const = 0;
|
||||
virtual void setShowWindow(bool newValue) = 0;
|
||||
|
||||
virtual bool getDesktopNotify() const = 0;
|
||||
virtual void setDesktopNotify(bool enabled) = 0;
|
||||
|
||||
virtual bool getNotifySound() const = 0;
|
||||
virtual void setNotifySound(bool newValue) = 0;
|
||||
|
||||
virtual bool getNotifyHide() const = 0;
|
||||
virtual void setNotifyHide(bool newValue) = 0;
|
||||
|
||||
virtual bool getBusySound() const = 0;
|
||||
virtual void setBusySound(bool newValue) = 0;
|
||||
|
||||
virtual bool getGroupAlwaysNotify() const = 0;
|
||||
virtual void setGroupAlwaysNotify(bool newValue) = 0;
|
||||
};
|
||||
|
||||
#endif /*INOTIFICATION_SETTINGS_H*/
|
|
@ -27,6 +27,7 @@
|
|||
#include "src/persistence/paths.h"
|
||||
#include "src/persistence/ifriendsettings.h"
|
||||
#include "src/persistence/igroupsettings.h"
|
||||
#include "src/persistence/inotificationsettings.h"
|
||||
#include "src/video/ivideosettings.h"
|
||||
|
||||
#include <QDateTime>
|
||||
|
@ -50,7 +51,8 @@ class Settings : public QObject,
|
|||
public IFriendSettings,
|
||||
public IGroupSettings,
|
||||
public IAudioSettings,
|
||||
public IVideoSettings
|
||||
public IVideoSettings,
|
||||
public INotificationSettings
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
|
@ -311,23 +313,23 @@ public:
|
|||
bool getCheckUpdates() const;
|
||||
void setCheckUpdates(bool newValue);
|
||||
|
||||
bool getNotify() const;
|
||||
void setNotify(bool newValue);
|
||||
bool getNotify() const override;
|
||||
void setNotify(bool newValue) override;
|
||||
|
||||
bool getShowWindow() const;
|
||||
void setShowWindow(bool newValue);
|
||||
bool getShowWindow() const override;
|
||||
void setShowWindow(bool newValue) override;
|
||||
|
||||
bool getDesktopNotify() const;
|
||||
void setDesktopNotify(bool enabled);
|
||||
bool getDesktopNotify() const override;
|
||||
void setDesktopNotify(bool enabled) override;
|
||||
|
||||
bool getNotifySound() const;
|
||||
void setNotifySound(bool newValue);
|
||||
bool getNotifySound() const override;
|
||||
void setNotifySound(bool newValue) override;
|
||||
|
||||
bool getNotifyHide() const;
|
||||
void setNotifyHide(bool newValue);
|
||||
bool getNotifyHide() const override;
|
||||
void setNotifyHide(bool newValue) override;
|
||||
|
||||
bool getBusySound() const;
|
||||
void setBusySound(bool newValue);
|
||||
bool getBusySound() const override;
|
||||
void setBusySound(bool newValue) override;
|
||||
|
||||
bool getGroupAlwaysNotify() const override;
|
||||
void setGroupAlwaysNotify(bool newValue) override;
|
||||
|
|
26
test/mock/mockcoreidhandler.h
Normal file
26
test/mock/mockcoreidhandler.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
#pragma once
|
||||
|
||||
#include "src/core/icoreidhandler.h"
|
||||
|
||||
#include <tox/tox.h>
|
||||
|
||||
class MockCoreIdHandler : public ICoreIdHandler
|
||||
{
|
||||
public:
|
||||
ToxId getSelfId() const override
|
||||
{
|
||||
std::terminate();
|
||||
return ToxId();
|
||||
}
|
||||
|
||||
ToxPk getSelfPublicKey() const override
|
||||
{
|
||||
static uint8_t id[TOX_PUBLIC_KEY_SIZE] = {0};
|
||||
return ToxPk(id);
|
||||
}
|
||||
|
||||
QString getUsername() const override
|
||||
{
|
||||
return "me";
|
||||
}
|
||||
};
|
63
test/mock/mockgroupquery.h
Normal file
63
test/mock/mockgroupquery.h
Normal file
|
@ -0,0 +1,63 @@
|
|||
#pragma once
|
||||
|
||||
#include "src/core/icoregroupquery.h"
|
||||
|
||||
#include <tox/tox.h>
|
||||
|
||||
/**
|
||||
* Mock 1 peer at group number 0
|
||||
*/
|
||||
class MockGroupQuery : public ICoreGroupQuery
|
||||
{
|
||||
public:
|
||||
GroupId getGroupPersistentId(uint32_t groupNumber) const override
|
||||
{
|
||||
return GroupId(0);
|
||||
}
|
||||
|
||||
uint32_t getGroupNumberPeers(int groupId) const override
|
||||
{
|
||||
if (emptyGroup) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
QString getGroupPeerName(int groupId, int peerId) const override
|
||||
{
|
||||
return QString("peer") + peerId;
|
||||
}
|
||||
|
||||
ToxPk getGroupPeerPk(int groupId, int peerId) const override
|
||||
{
|
||||
uint8_t id[TOX_PUBLIC_KEY_SIZE] = {static_cast<uint8_t>(peerId)};
|
||||
return ToxPk(id);
|
||||
}
|
||||
|
||||
QStringList getGroupPeerNames(int groupId) const override
|
||||
{
|
||||
if (emptyGroup) {
|
||||
return QStringList({QString("me")});
|
||||
}
|
||||
return QStringList({QString("me"), QString("other")});
|
||||
}
|
||||
|
||||
bool getGroupAvEnabled(int groupId) const override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void setAsEmptyGroup()
|
||||
{
|
||||
emptyGroup = true;
|
||||
}
|
||||
|
||||
void setAsFunctionalGroup()
|
||||
{
|
||||
emptyGroup = false;
|
||||
}
|
||||
|
||||
private:
|
||||
bool emptyGroup = false;
|
||||
};
|
|
@ -23,6 +23,9 @@
|
|||
#include "src/model/message.h"
|
||||
#include "src/persistence/settings.h"
|
||||
|
||||
#include "test/mock/mockcoreidhandler.h"
|
||||
#include "test/mock/mockgroupquery.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QtTest/QtTest>
|
||||
|
||||
|
@ -47,85 +50,6 @@ public:
|
|||
size_t numSentMessages = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Mock 1 peer at group number 0
|
||||
*/
|
||||
class MockGroupQuery : public ICoreGroupQuery
|
||||
{
|
||||
public:
|
||||
GroupId getGroupPersistentId(uint32_t groupNumber) const override
|
||||
{
|
||||
return GroupId();
|
||||
}
|
||||
|
||||
uint32_t getGroupNumberPeers(int groupId) const override
|
||||
{
|
||||
if (emptyGroup) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
QString getGroupPeerName(int groupId, int peerId) const override
|
||||
{
|
||||
return QString("peer") + peerId;
|
||||
}
|
||||
|
||||
ToxPk getGroupPeerPk(int groupId, int peerId) const override
|
||||
{
|
||||
uint8_t id[TOX_PUBLIC_KEY_SIZE] = {static_cast<uint8_t>(peerId)};
|
||||
return ToxPk(id);
|
||||
}
|
||||
|
||||
QStringList getGroupPeerNames(int groupId) const override
|
||||
{
|
||||
if (emptyGroup) {
|
||||
return QStringList({QString("me")});
|
||||
}
|
||||
return QStringList({QString("me"), QString("other")});
|
||||
}
|
||||
|
||||
bool getGroupAvEnabled(int groupId) const override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void setAsEmptyGroup()
|
||||
{
|
||||
emptyGroup = true;
|
||||
}
|
||||
|
||||
void setAsFunctionalGroup()
|
||||
{
|
||||
emptyGroup = false;
|
||||
}
|
||||
|
||||
private:
|
||||
bool emptyGroup = false;
|
||||
};
|
||||
|
||||
class MockCoreIdHandler : public ICoreIdHandler
|
||||
{
|
||||
public:
|
||||
ToxId getSelfId() const override
|
||||
{
|
||||
std::terminate();
|
||||
return ToxId();
|
||||
}
|
||||
|
||||
ToxPk getSelfPublicKey() const override
|
||||
{
|
||||
static uint8_t id[TOX_PUBLIC_KEY_SIZE] = {0};
|
||||
return ToxPk(id);
|
||||
}
|
||||
|
||||
QString getUsername() const override
|
||||
{
|
||||
return "me";
|
||||
}
|
||||
};
|
||||
|
||||
class MockGroupSettings : public IGroupSettings
|
||||
{
|
||||
public:
|
||||
|
@ -139,13 +63,6 @@ public:
|
|||
blacklist = blist;
|
||||
}
|
||||
|
||||
bool getGroupAlwaysNotify() const override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void setGroupAlwaysNotify(bool newValue) override {}
|
||||
|
||||
private:
|
||||
QStringList blacklist;
|
||||
};
|
||||
|
|
375
test/model/notificationgenerator_test.cpp
Normal file
375
test/model/notificationgenerator_test.cpp
Normal file
|
@ -0,0 +1,375 @@
|
|||
|
||||
/*
|
||||
Copyright © 2019 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/notificationgenerator.h"
|
||||
|
||||
#include "test/mock/mockcoreidhandler.h"
|
||||
#include "test/mock/mockgroupquery.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QtTest/QtTest>
|
||||
|
||||
namespace
|
||||
{
|
||||
class MockNotificationSettings : public INotificationSettings
|
||||
{
|
||||
virtual bool getNotify() const override { return true; }
|
||||
|
||||
virtual void setNotify(bool newValue) override {}
|
||||
|
||||
virtual bool getShowWindow() const override { return true; }
|
||||
virtual void setShowWindow(bool newValue) override {}
|
||||
|
||||
virtual bool getDesktopNotify() const override { return true; }
|
||||
virtual void setDesktopNotify(bool enabled) override {}
|
||||
|
||||
virtual bool getNotifySound() const override { return true; }
|
||||
virtual void setNotifySound(bool newValue) override {}
|
||||
|
||||
virtual bool getNotifyHide() const override { return notifyHide; }
|
||||
virtual void setNotifyHide(bool newValue) override { notifyHide = newValue; };
|
||||
|
||||
virtual bool getBusySound() const override { return true; }
|
||||
virtual void setBusySound(bool newValue) override {}
|
||||
|
||||
virtual bool getGroupAlwaysNotify() const override { return true; }
|
||||
virtual void setGroupAlwaysNotify(bool newValue) override {}
|
||||
private:
|
||||
bool notifyHide = false;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
class TestNotificationGenerator : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void init();
|
||||
void testSingleFriendMessage();
|
||||
void testMultipleFriendMessages();
|
||||
void testNotificationClear();
|
||||
void testGroupMessage();
|
||||
void testMultipleGroupMessages();
|
||||
void testMultipleFriendSourceMessages();
|
||||
void testMultipleGroupSourceMessages();
|
||||
void testMixedSourceMessages();
|
||||
void testFileTransfer();
|
||||
void testFileTransferAfterMessage();
|
||||
void testGroupInvitation();
|
||||
void testGroupInviteUncounted();
|
||||
void testFriendRequest();
|
||||
void testFriendRequestUncounted();
|
||||
void testSimpleFriendMessage();
|
||||
void testSimpleFileTransfer();
|
||||
void testSimpleGroupMessage();
|
||||
void testSimpleFriendRequest();
|
||||
void testSimpleGroupInvite();
|
||||
void testSimpleMessageToggle();
|
||||
|
||||
private:
|
||||
std::unique_ptr<INotificationSettings> notificationSettings;
|
||||
std::unique_ptr<NotificationGenerator> notificationGenerator;
|
||||
std::unique_ptr<MockGroupQuery> groupQuery;
|
||||
std::unique_ptr<MockCoreIdHandler> coreIdHandler;
|
||||
};
|
||||
|
||||
void TestNotificationGenerator::init()
|
||||
{
|
||||
notificationSettings.reset(new MockNotificationSettings());
|
||||
notificationGenerator.reset(new NotificationGenerator(*notificationSettings, nullptr));
|
||||
groupQuery.reset(new MockGroupQuery());
|
||||
coreIdHandler.reset(new MockCoreIdHandler());
|
||||
}
|
||||
|
||||
void TestNotificationGenerator::testSingleFriendMessage()
|
||||
{
|
||||
Friend f(0, ToxPk());
|
||||
f.setName("friendName");
|
||||
auto notificationData = notificationGenerator->friendMessageNotification(&f, "test");
|
||||
QVERIFY(notificationData.title == "friendName");
|
||||
QVERIFY(notificationData.message == "test");
|
||||
}
|
||||
|
||||
void TestNotificationGenerator::testMultipleFriendMessages()
|
||||
{
|
||||
Friend f(0, ToxPk());
|
||||
f.setName("friendName");
|
||||
notificationGenerator->friendMessageNotification(&f, "test");
|
||||
auto notificationData = notificationGenerator->friendMessageNotification(&f, "test2");
|
||||
QVERIFY(notificationData.title == "2 messages from friendName");
|
||||
QVERIFY(notificationData.message == "test2");
|
||||
|
||||
notificationData = notificationGenerator->friendMessageNotification(&f, "test3");
|
||||
QVERIFY(notificationData.title == "3 messages from friendName");
|
||||
QVERIFY(notificationData.message == "test3");
|
||||
}
|
||||
|
||||
void TestNotificationGenerator::testNotificationClear()
|
||||
{
|
||||
Friend f(0, ToxPk());
|
||||
f.setName("friendName");
|
||||
|
||||
notificationGenerator->friendMessageNotification(&f, "test");
|
||||
|
||||
// On notification clear we shouldn't see a notification count from the friend
|
||||
notificationGenerator->onNotificationActivated();
|
||||
|
||||
auto notificationData = notificationGenerator->friendMessageNotification(&f, "test2");
|
||||
QVERIFY(notificationData.title == "friendName");
|
||||
QVERIFY(notificationData.message == "test2");
|
||||
}
|
||||
|
||||
void TestNotificationGenerator::testGroupMessage()
|
||||
{
|
||||
Group g(0, GroupId(0), "groupName", false, "selfName", *groupQuery, *coreIdHandler);
|
||||
g.setName("groupName");
|
||||
auto sender = groupQuery->getGroupPeerPk(0, 0);
|
||||
g.updateUsername(sender, "sender1");
|
||||
|
||||
auto notificationData = notificationGenerator->groupMessageNotification(&g, sender, "test");
|
||||
QVERIFY(notificationData.title == "groupName");
|
||||
QVERIFY(notificationData.message == "sender1: test");
|
||||
}
|
||||
|
||||
void TestNotificationGenerator::testMultipleGroupMessages()
|
||||
{
|
||||
Group g(0, GroupId(0), "groupName", false, "selfName", *groupQuery, *coreIdHandler);
|
||||
g.setName("groupName");
|
||||
auto sender = groupQuery->getGroupPeerPk(0, 0);
|
||||
g.updateUsername(sender, "sender1");
|
||||
|
||||
auto sender2 = groupQuery->getGroupPeerPk(0, 1);
|
||||
g.updateUsername(sender2, "sender2");
|
||||
|
||||
auto notificationData = notificationGenerator->groupMessageNotification(&g, sender2, "test2");
|
||||
QVERIFY(notificationData.title == "groupName");
|
||||
QVERIFY(notificationData.message == "sender2: test2");
|
||||
}
|
||||
|
||||
void TestNotificationGenerator::testMultipleFriendSourceMessages()
|
||||
{
|
||||
Friend f(0, ToxPk());
|
||||
f.setName("friend1");
|
||||
|
||||
Friend f2(1, ToxPk());
|
||||
f2.setName("friend2");
|
||||
|
||||
notificationGenerator->friendMessageNotification(&f, "test1");
|
||||
auto notificationData = notificationGenerator->friendMessageNotification(&f2, "test2");
|
||||
|
||||
QVERIFY(notificationData.title == "2 messages from 2 chats");
|
||||
QVERIFY(notificationData.message == "friend1, friend2");
|
||||
}
|
||||
|
||||
void TestNotificationGenerator::testMultipleGroupSourceMessages()
|
||||
{
|
||||
Group g(0, GroupId(QByteArray(32, 0)), "groupName", false, "selfName", *groupQuery, *coreIdHandler);
|
||||
g.setName("groupName");
|
||||
|
||||
Group g2(1, GroupId(QByteArray(32, 1)), "groupName", false, "selfName", *groupQuery, *coreIdHandler);
|
||||
g.setName("groupName2");
|
||||
|
||||
auto sender = groupQuery->getGroupPeerPk(0, 0);
|
||||
g.updateUsername(sender, "sender1");
|
||||
|
||||
notificationGenerator->groupMessageNotification(&g, sender, "test1");
|
||||
auto notificationData = notificationGenerator->groupMessageNotification(&g2, sender, "test1");
|
||||
|
||||
QVERIFY(notificationData.title == "2 messages from 2 chats");
|
||||
QVERIFY(notificationData.message == "groupName, groupName2");
|
||||
}
|
||||
|
||||
void TestNotificationGenerator::testMixedSourceMessages()
|
||||
{
|
||||
Friend f(0, ToxPk());
|
||||
f.setName("friend");
|
||||
|
||||
Group g(0, GroupId(QByteArray(32, 0)), "groupName", false, "selfName", *groupQuery, *coreIdHandler);
|
||||
g.setName("group");
|
||||
|
||||
auto sender = groupQuery->getGroupPeerPk(0, 0);
|
||||
g.updateUsername(sender, "sender1");
|
||||
|
||||
notificationGenerator->friendMessageNotification(&f, "test1");
|
||||
auto notificationData = notificationGenerator->groupMessageNotification(&g, sender, "test2");
|
||||
|
||||
QVERIFY(notificationData.title == "2 messages from 2 chats");
|
||||
QVERIFY(notificationData.message == "friend, group");
|
||||
|
||||
notificationData = notificationGenerator->fileTransferNotification(&f, "file", 0);
|
||||
QVERIFY(notificationData.title == "3 messages from 2 chats");
|
||||
QVERIFY(notificationData.message == "friend, group");
|
||||
}
|
||||
|
||||
void TestNotificationGenerator::testFileTransfer()
|
||||
{
|
||||
Friend f(0, ToxPk());
|
||||
f.setName("friend");
|
||||
|
||||
auto notificationData = notificationGenerator->fileTransferNotification(&f, "file", 5 * 1024 * 1024 /* 5MB */);
|
||||
|
||||
QVERIFY(notificationData.title == "friend - File sent");
|
||||
QVERIFY(notificationData.message == "file (5.00MiB)");
|
||||
}
|
||||
|
||||
void TestNotificationGenerator::testFileTransferAfterMessage()
|
||||
{
|
||||
Friend f(0, ToxPk());
|
||||
f.setName("friend");
|
||||
|
||||
notificationGenerator->friendMessageNotification(&f, "test1");
|
||||
auto notificationData = notificationGenerator->fileTransferNotification(&f, "file", 5 * 1024 * 1024 /* 5MB */);
|
||||
|
||||
QVERIFY(notificationData.title == "2 messages from friend");
|
||||
QVERIFY(notificationData.message == "Incoming file transfer");
|
||||
}
|
||||
|
||||
void TestNotificationGenerator::testGroupInvitation()
|
||||
{
|
||||
Friend f(0, ToxPk());
|
||||
f.setName("friend");
|
||||
|
||||
auto notificationData = notificationGenerator->groupInvitationNotification(&f);
|
||||
|
||||
QVERIFY(notificationData.title == "friend invites you to join a group.");
|
||||
QVERIFY(notificationData.message == "");
|
||||
}
|
||||
|
||||
void TestNotificationGenerator::testGroupInviteUncounted()
|
||||
{
|
||||
Friend f(0, ToxPk());
|
||||
f.setName("friend");
|
||||
|
||||
notificationGenerator->friendMessageNotification(&f, "test");
|
||||
notificationGenerator->groupInvitationNotification(&f);
|
||||
auto notificationData = notificationGenerator->friendMessageNotification(&f, "test2");
|
||||
|
||||
QVERIFY(notificationData.title == "2 messages from friend");
|
||||
QVERIFY(notificationData.message == "test2");
|
||||
}
|
||||
|
||||
void TestNotificationGenerator::testFriendRequest()
|
||||
{
|
||||
ToxPk sender(QByteArray(32, 0));
|
||||
|
||||
auto notificationData = notificationGenerator->friendRequestNotification(sender, "request");
|
||||
|
||||
QVERIFY(notificationData.title == "0000000000000000000000000000000000000000000000000000000000000000 sent you a friend request.");
|
||||
QVERIFY(notificationData.message == "request");
|
||||
}
|
||||
|
||||
void TestNotificationGenerator::testFriendRequestUncounted()
|
||||
{
|
||||
Friend f(0, ToxPk());
|
||||
f.setName("friend");
|
||||
ToxPk sender(QByteArray(32, 0));
|
||||
|
||||
notificationGenerator->friendMessageNotification(&f, "test");
|
||||
notificationGenerator->friendRequestNotification(sender, "request");
|
||||
auto notificationData = notificationGenerator->friendMessageNotification(&f, "test2");
|
||||
|
||||
QVERIFY(notificationData.title == "2 messages from friend");
|
||||
QVERIFY(notificationData.message == "test2");
|
||||
}
|
||||
|
||||
void TestNotificationGenerator::testSimpleFriendMessage()
|
||||
{
|
||||
Friend f(0, ToxPk());
|
||||
f.setName("friend");
|
||||
|
||||
notificationSettings->setNotifyHide(true);
|
||||
|
||||
auto notificationData = notificationGenerator->friendMessageNotification(&f, "test");
|
||||
|
||||
QVERIFY(notificationData.title == "New message");
|
||||
QVERIFY(notificationData.message == "");
|
||||
}
|
||||
|
||||
void TestNotificationGenerator::testSimpleFileTransfer()
|
||||
{
|
||||
Friend f(0, ToxPk());
|
||||
f.setName("friend");
|
||||
|
||||
notificationSettings->setNotifyHide(true);
|
||||
|
||||
auto notificationData = notificationGenerator->fileTransferNotification(&f, "file", 0);
|
||||
|
||||
QVERIFY(notificationData.title == "Incoming file transfer");
|
||||
QVERIFY(notificationData.message == "");
|
||||
}
|
||||
|
||||
void TestNotificationGenerator::testSimpleGroupMessage()
|
||||
{
|
||||
Group g(0, GroupId(0), "groupName", false, "selfName", *groupQuery, *coreIdHandler);
|
||||
g.setName("groupName");
|
||||
auto sender = groupQuery->getGroupPeerPk(0, 0);
|
||||
g.updateUsername(sender, "sender1");
|
||||
|
||||
notificationSettings->setNotifyHide(true);
|
||||
|
||||
auto notificationData = notificationGenerator->groupMessageNotification(&g, sender, "test");
|
||||
QVERIFY(notificationData.title == "New group message");
|
||||
QVERIFY(notificationData.message == "");
|
||||
}
|
||||
|
||||
void TestNotificationGenerator::testSimpleFriendRequest()
|
||||
{
|
||||
ToxPk sender(QByteArray(32, 0));
|
||||
|
||||
notificationSettings->setNotifyHide(true);
|
||||
|
||||
auto notificationData = notificationGenerator->friendRequestNotification(sender, "request");
|
||||
|
||||
QVERIFY(notificationData.title == "Friend request received");
|
||||
QVERIFY(notificationData.message == "");
|
||||
}
|
||||
|
||||
void TestNotificationGenerator::testSimpleGroupInvite()
|
||||
{
|
||||
Friend f(0, ToxPk());
|
||||
f.setName("friend");
|
||||
|
||||
notificationSettings->setNotifyHide(true);
|
||||
auto notificationData = notificationGenerator->groupInvitationNotification(&f);
|
||||
|
||||
QVERIFY(notificationData.title == "Group invite received");
|
||||
QVERIFY(notificationData.message == "");
|
||||
}
|
||||
|
||||
void TestNotificationGenerator::testSimpleMessageToggle()
|
||||
{
|
||||
Friend f(0, ToxPk());
|
||||
f.setName("friend");
|
||||
|
||||
notificationSettings->setNotifyHide(true);
|
||||
|
||||
notificationGenerator->friendMessageNotification(&f, "test");
|
||||
|
||||
notificationSettings->setNotifyHide(false);
|
||||
|
||||
auto notificationData = notificationGenerator->friendMessageNotification(&f, "test2");
|
||||
|
||||
QVERIFY(notificationData.title == "2 messages from friend");
|
||||
QVERIFY(notificationData.message == "test2");
|
||||
}
|
||||
|
||||
QTEST_GUILESS_MAIN(TestNotificationGenerator)
|
||||
#include "notificationgenerator_test.moc"
|
Loading…
Reference in New Issue
Block a user