mirror of
https://github.com/ars3niy/tdlib-purple
synced 2025-08-31 14:05:10 +00:00
Implemented room list (mostly for bitlbee and spectrum)
This commit is contained in:
@@ -481,7 +481,7 @@ const td::td_api::chat *TdAccountData::getSupergroupChatByGroup(int32_t groupId)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool TdAccountData::isGroupChatWithMembership(const td::td_api::chat &chat)
|
||||
bool TdAccountData::isGroupChatWithMembership(const td::td_api::chat &chat) const
|
||||
{
|
||||
int groupId = getBasicGroupId(chat);
|
||||
if (groupId) {
|
||||
|
@@ -218,13 +218,14 @@ public:
|
||||
std::string getDisplayName(int32_t userId) const;
|
||||
void getUsersByDisplayName(const char *displayName,
|
||||
std::vector<const td::td_api::user*> &users);
|
||||
|
||||
const td::td_api::basicGroup *getBasicGroup(int32_t groupId) const;
|
||||
const td::td_api::basicGroupFullInfo *getBasicGroupInfo(int32_t groupId) const;
|
||||
const td::td_api::supergroup *getSupergroup(int32_t groupId) const;
|
||||
const td::td_api::supergroupFullInfo *getSupergroupInfo(int32_t groupId) const;
|
||||
const td::td_api::chat *getBasicGroupChatByGroup(int32_t groupId) const;
|
||||
const td::td_api::chat *getSupergroupChatByGroup(int32_t groupId) const;
|
||||
bool isGroupChatWithMembership(const td::td_api::chat &chat);
|
||||
bool isGroupChatWithMembership(const td::td_api::chat &chat) const;
|
||||
|
||||
template<typename ReqType, typename... ArgsType>
|
||||
void addPendingRequest(ArgsType... args)
|
||||
|
@@ -147,7 +147,7 @@ PurpleConversation *getImConversation(PurpleAccount *account, const char *userna
|
||||
PurpleConvChat *getChatConversation(TdAccountData &account, const td::td_api::chat &chat,
|
||||
int chatPurpleId)
|
||||
{
|
||||
std::string chatName = getChatName(chat);
|
||||
std::string chatName = getPurpleChatName(chat);
|
||||
bool newChatCreated = false;
|
||||
PurpleConversation *conv = purple_find_chat(purple_account_get_connection(account.purpleAccount), chatPurpleId);
|
||||
if (conv == NULL) {
|
||||
@@ -199,7 +199,7 @@ PurpleConvChat *getChatConversation(TdAccountData &account, const td::td_api::ch
|
||||
|
||||
PurpleConvChat *findChatConversation(PurpleAccount *account, const td::td_api::chat &chat)
|
||||
{
|
||||
std::string name = getChatName(chat);
|
||||
std::string name = getPurpleChatName(chat);
|
||||
PurpleConversation *conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,
|
||||
name.c_str(), account);
|
||||
if (conv)
|
||||
@@ -296,7 +296,7 @@ static void updateGroupChat(PurpleAccount *purpleAccount, const td::td_api::chat
|
||||
return;
|
||||
}
|
||||
|
||||
std::string chatName = getChatName(chat);
|
||||
std::string chatName = getPurpleChatName(chat);
|
||||
PurpleChat *purpleChat = purple_blist_find_chat(purpleAccount, chatName.c_str());
|
||||
if (!purpleChat) {
|
||||
purple_debug_misc(config::pluginId, "Adding new chat for %s %d (%s)\n",
|
||||
@@ -370,7 +370,7 @@ void updateSupergroupChat(TdAccountData &account, int32_t groupId)
|
||||
|
||||
void removeGroupChat(PurpleAccount *purpleAccount, const td::td_api::chat &chat)
|
||||
{
|
||||
std::string chatName = getChatName(chat);
|
||||
std::string chatName = getPurpleChatName(chat);
|
||||
PurpleChat *purpleChat = purple_blist_find_chat(purpleAccount, chatName.c_str());
|
||||
|
||||
if (purpleChat)
|
||||
@@ -1473,3 +1473,28 @@ void updateOption(const td::td_api::updateOption &option, TdAccountData &account
|
||||
} else
|
||||
purple_debug_misc(config::pluginId, "Option update %s\n", option.name_.c_str());
|
||||
}
|
||||
|
||||
void populateGroupChatList(PurpleRoomlist *roomlist, const std::vector<const td::td_api::chat *> &chats,
|
||||
const TdAccountData &account)
|
||||
{
|
||||
for (const td::td_api::chat *chat: chats)
|
||||
if (account.isGroupChatWithMembership(*chat)) {
|
||||
PurpleRoomlistRoom *room = purple_roomlist_room_new(PURPLE_ROOMLIST_ROOMTYPE_ROOM,
|
||||
chat->title_.c_str(), NULL);
|
||||
purple_roomlist_room_add_field (roomlist, room, getPurpleChatName(*chat).c_str());
|
||||
int32_t groupId = getBasicGroupId(*chat);
|
||||
if (groupId) {
|
||||
const td::td_api::basicGroupFullInfo *fullInfo = account.getBasicGroupInfo(groupId);
|
||||
if (fullInfo && !fullInfo->description_.empty())
|
||||
purple_roomlist_room_add_field(roomlist, room, fullInfo->description_.c_str());
|
||||
}
|
||||
groupId = getSupergroupId(*chat);
|
||||
if (groupId) {
|
||||
const td::td_api::supergroupFullInfo *fullInfo = account.getSupergroupInfo(groupId);
|
||||
if (fullInfo && !fullInfo->description_.empty())
|
||||
purple_roomlist_room_add_field(roomlist, room, fullInfo->description_.c_str());
|
||||
}
|
||||
purple_roomlist_room_add(roomlist, room);
|
||||
}
|
||||
purple_roomlist_set_in_progress(roomlist, FALSE);
|
||||
}
|
||||
|
@@ -87,5 +87,7 @@ std::string makeDocumentDescription(const td::td_api::videoNote *document);
|
||||
void updateSecretChat(td::td_api::object_ptr<td::td_api::secretChat> secretChat,
|
||||
TdTransceiver &transceiver, TdAccountData &account);
|
||||
void updateOption(const td::td_api::updateOption &option, TdAccountData &account);
|
||||
void populateGroupChatList(PurpleRoomlist *roomlist, const std::vector<const td::td_api::chat *> &chats,
|
||||
const TdAccountData &account);
|
||||
|
||||
#endif
|
||||
|
@@ -6,10 +6,15 @@
|
||||
|
||||
static const char *_(const char *s) { return s; }
|
||||
|
||||
static char idKey[] = "id";
|
||||
static char inviteKey[] = "link";
|
||||
static char nameKey[] = "name";
|
||||
static char typeKey[] = "type";
|
||||
static char chatNameComponent[] = "id";
|
||||
static char inviteKey[] = "link";
|
||||
static char nameKey[] = "name";
|
||||
static char typeKey[] = "type";
|
||||
|
||||
const char *getChatNameComponent()
|
||||
{
|
||||
return chatNameComponent;
|
||||
}
|
||||
|
||||
GList *getChatJoinInfo()
|
||||
{
|
||||
@@ -17,7 +22,7 @@ GList *getChatJoinInfo()
|
||||
struct proto_chat_entry *pce;
|
||||
pce = g_new0 (struct proto_chat_entry, 1);
|
||||
pce->label = _("Chat ID (don't change):");
|
||||
pce->identifier = idKey;
|
||||
pce->identifier = chatNameComponent;
|
||||
pce->required = FALSE;
|
||||
GList *info = g_list_append (NULL, pce);
|
||||
|
||||
@@ -46,7 +51,7 @@ GList *getChatJoinInfo()
|
||||
return info;
|
||||
}
|
||||
|
||||
std::string getChatName(const td::td_api::chat &chat)
|
||||
std::string getPurpleChatName(const td::td_api::chat &chat)
|
||||
{
|
||||
return "chat" + std::to_string(chat.id_);
|
||||
}
|
||||
@@ -58,13 +63,13 @@ GHashTable *getChatComponents(const td::td_api::chat &chat)
|
||||
name[sizeof(name)-1] = '\0';
|
||||
|
||||
GHashTable *table = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
|
||||
g_hash_table_insert(table, idKey, g_strdup(name));
|
||||
g_hash_table_insert(table, chatNameComponent, g_strdup(name));
|
||||
return table;
|
||||
}
|
||||
|
||||
const char *getChatName(GHashTable *components)
|
||||
{
|
||||
return (const char *)g_hash_table_lookup(components, idKey);
|
||||
return (const char *)g_hash_table_lookup(components, chatNameComponent);
|
||||
}
|
||||
|
||||
const char *getChatInviteLink(GHashTable *components)
|
||||
|
@@ -9,8 +9,9 @@ static constexpr int
|
||||
GROUP_TYPE_SUPER = 2,
|
||||
GROUP_TYPE_CHANNEL = 3;
|
||||
|
||||
const char *getChatNameComponent();
|
||||
GList *getChatJoinInfo();
|
||||
std::string getChatName(const td::td_api::chat &chat);
|
||||
std::string getPurpleChatName(const td::td_api::chat &chat);
|
||||
GHashTable *getChatComponents(const td::td_api::chat &chat);
|
||||
|
||||
const char *getChatName(GHashTable *components);
|
||||
|
@@ -769,6 +769,12 @@ void PurpleTdClient::updatePurpleChatListAndReportConnected()
|
||||
}
|
||||
}
|
||||
|
||||
for (PurpleRoomlist *roomlist: m_pendingRoomLists) {
|
||||
populateGroupChatList(roomlist, chats, m_data);
|
||||
purple_roomlist_unref(roomlist);
|
||||
}
|
||||
m_pendingRoomLists.clear();
|
||||
|
||||
// Here we could remove buddies for which no private chat exists, meaning they have been remove
|
||||
// from the contact list perhaps in another client
|
||||
|
||||
@@ -2054,6 +2060,29 @@ void PurpleTdClient::showInviteLink(const std::string& purpleChatName)
|
||||
showChatNotification(m_data, *chat, "Failed to get invite link, full info not known");
|
||||
}
|
||||
|
||||
void PurpleTdClient::getGroupChatList(PurpleRoomlist *roomlist)
|
||||
{
|
||||
|
||||
GList *fields = NULL;
|
||||
PurpleRoomlistField *f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, "",
|
||||
getChatNameComponent(), TRUE);
|
||||
fields = g_list_append (fields, f);
|
||||
// "description" is hard-coded in bitlbee as possible field for chat topic
|
||||
f = purple_roomlist_field_new(PURPLE_ROOMLIST_FIELD_STRING, _("Description"), "description", FALSE);
|
||||
fields = g_list_append (fields, f);
|
||||
purple_roomlist_set_fields (roomlist, fields);
|
||||
|
||||
purple_roomlist_set_in_progress(roomlist, TRUE);
|
||||
if (purple_account_is_connected(m_account)) {
|
||||
std::vector<const td::td_api::chat *> chats;
|
||||
m_data.getChats(chats);
|
||||
populateGroupChatList(roomlist, chats, m_data);
|
||||
} else {
|
||||
purple_roomlist_ref(roomlist);
|
||||
m_pendingRoomLists.push_back(roomlist);
|
||||
}
|
||||
}
|
||||
|
||||
void PurpleTdClient::removeTempFile(int64_t messageId)
|
||||
{
|
||||
std::string path = m_data.extractTempFileUpload(messageId);
|
||||
|
@@ -39,6 +39,7 @@ public:
|
||||
void kickUserFromChat(PurpleConversation *conv, const char *name);
|
||||
void addUserToChat(int purpleChatId, const char *name);
|
||||
void showInviteLink(const std::string &purpleChatName);
|
||||
void getGroupChatList(PurpleRoomlist *roomlist);
|
||||
|
||||
void setTwoFactorAuth(const char *oldPassword, const char *newPassword, const char *hint,
|
||||
const char *email);
|
||||
@@ -170,6 +171,7 @@ private:
|
||||
std::vector<int32_t> m_usersForNewPrivateChats;
|
||||
bool m_isProxyAdded = false;
|
||||
int64_t m_lastChatOrderOffset = 0;
|
||||
std::vector<PurpleRoomlist *> m_pendingRoomLists;
|
||||
td::td_api::object_ptr<td::td_api::proxy> m_addedProxy;
|
||||
td::td_api::object_ptr<td::td_api::proxies> m_proxies;
|
||||
};
|
||||
|
@@ -212,7 +212,9 @@ static GList *tgprpl_chat_join_info (PurpleConnection *gc)
|
||||
|
||||
static GHashTable *tgprpl_chat_info_defaults (PurpleConnection *gc, const char *chat_name)
|
||||
{
|
||||
return g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
|
||||
GHashTable *components = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
|
||||
g_hash_table_insert(components, (gpointer)getChatNameComponent(), g_strdup(chat_name));
|
||||
return components;
|
||||
}
|
||||
|
||||
static ITransceiverBackend *g_testBackend = nullptr;
|
||||
@@ -451,15 +453,11 @@ static void tgprpl_rename_buddy(PurpleConnection *gc, const char *who, const cha
|
||||
|
||||
static PurpleRoomlist *tgprpl_roomlist_get_list (PurpleConnection *gc)
|
||||
{
|
||||
static PurpleRoomlist *roomlist = NULL; // put it on like protocol_data
|
||||
PurpleTdClient *tdClient = static_cast<PurpleTdClient *>(purple_connection_get_protocol_data(gc));
|
||||
PurpleRoomlist *roomlist = purple_roomlist_new(purple_connection_get_account(gc));
|
||||
|
||||
if (roomlist)
|
||||
purple_roomlist_unref (roomlist);
|
||||
roomlist = purple_roomlist_new (purple_connection_get_account (gc));
|
||||
|
||||
purple_roomlist_set_in_progress (roomlist, TRUE);
|
||||
// blah blah blah
|
||||
purple_roomlist_set_in_progress (roomlist, FALSE);
|
||||
if (tdClient)
|
||||
tdClient->getGroupChatList(roomlist);
|
||||
|
||||
return roomlist;
|
||||
}
|
||||
@@ -468,6 +466,11 @@ static void tgprpl_roomlist_cancel (PurpleRoomlist *list)
|
||||
{
|
||||
}
|
||||
|
||||
static char *getRoomlistChatName(PurpleRoomlistRoom *room)
|
||||
{
|
||||
return g_strdup((char *)purple_roomlist_room_get_fields(room)->data);
|
||||
}
|
||||
|
||||
static gboolean tgprpl_can_receive_file (PurpleConnection *gc, const char *who)
|
||||
{
|
||||
return TRUE;
|
||||
@@ -615,7 +618,7 @@ static PurplePluginProtocolInfo prpl_info = {
|
||||
.offline_message = NULL,
|
||||
.whiteboard_prpl_ops = NULL,
|
||||
.send_raw = NULL,
|
||||
.roomlist_room_serialize = NULL,
|
||||
.roomlist_room_serialize = getRoomlistChatName,
|
||||
.unregister_user = NULL,
|
||||
.send_attention = NULL,
|
||||
.get_attention_types = NULL,
|
||||
|
@@ -1208,3 +1208,103 @@ TEST_F(GroupChatTest, GetInviteLink)
|
||||
|
||||
g_list_free_full(actions, (GDestroyNotify)purple_menu_action_free);
|
||||
}
|
||||
|
||||
TEST_F(GroupChatTest, Roomlist)
|
||||
{
|
||||
pluginInfo().login(account);
|
||||
PurpleRoomlist *superEarlyRoomlist = pluginInfo().roomlist_get_list(connection);
|
||||
prpl.verifyEvents(RoomlistInProgressEvent(superEarlyRoomlist, TRUE));
|
||||
|
||||
tgl.update(make_object<updateAuthorizationState>(make_object<authorizationStateWaitTdlibParameters>()));
|
||||
tgl.verifyRequests({
|
||||
make_object<disableProxy>(),
|
||||
make_object<getProxies>(),
|
||||
make_object<setTdlibParameters>(make_object<tdlibParameters>(
|
||||
false,
|
||||
std::string(purple_user_dir()) + G_DIR_SEPARATOR_S +
|
||||
"tdlib" + G_DIR_SEPARATOR_S + "+" + selfPhoneNumber,
|
||||
"",
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
0,
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
false,
|
||||
false
|
||||
))
|
||||
});
|
||||
tgl.reply(make_object<ok>());
|
||||
|
||||
tgl.update(make_object<updateAuthorizationState>(make_object<authorizationStateWaitEncryptionKey>(true)));
|
||||
tgl.verifyRequest(checkDatabaseEncryptionKey(""));
|
||||
tgl.reply(make_object<ok>());
|
||||
|
||||
tgl.update(make_object<updateAuthorizationState>(make_object<authorizationStateReady>()));
|
||||
tgl.verifyNoRequests();
|
||||
|
||||
tgl.update(make_object<updateConnectionState>(make_object<connectionStateConnecting>()));
|
||||
tgl.verifyNoRequests();
|
||||
prpl.verifyEvents(
|
||||
ConnectionSetStateEvent(connection, PURPLE_CONNECTING),
|
||||
ConnectionUpdateProgressEvent(connection, 1, 3)
|
||||
);
|
||||
|
||||
tgl.update(make_object<updateConnectionState>(make_object<connectionStateUpdating>()));
|
||||
tgl.verifyNoRequests();
|
||||
prpl.verifyEvents(ConnectionUpdateProgressEvent(connection, 2, 3));
|
||||
|
||||
tgl.update(make_object<updateUser>(makeUser(
|
||||
selfId,
|
||||
selfFirstName,
|
||||
selfLastName,
|
||||
selfPhoneNumber, // Phone number here without + to make it more interesting
|
||||
make_object<userStatusOffline>()
|
||||
)));
|
||||
tgl.update(make_object<updateBasicGroup>(make_object<basicGroup>(
|
||||
groupId, 2, make_object<chatMemberStatusMember>(), true, 0
|
||||
)));
|
||||
tgl.update(make_object<updateNewChat>(makeChat(
|
||||
groupChatId, make_object<chatTypeBasicGroup>(groupId), groupChatTitle, nullptr, 0, 0, 0
|
||||
)));
|
||||
tgl.update(makeUpdateChatListMain(groupChatId));
|
||||
|
||||
tgl.update(make_object<updateConnectionState>(make_object<connectionStateReady>()));
|
||||
tgl.verifyRequest(getContacts());
|
||||
tgl.reply(make_object<users>());
|
||||
|
||||
PurpleRoomlist *earlyRoomlist = pluginInfo().roomlist_get_list(connection);
|
||||
prpl.verifyEvents(RoomlistInProgressEvent(earlyRoomlist, TRUE));
|
||||
|
||||
tgl.verifyRequest(getChats());
|
||||
tgl.reply(make_object<chats>(std::vector<int64_t>(1, groupChatId)));
|
||||
tgl.verifyRequest(getChats());
|
||||
tgl.reply(make_object<chats>());
|
||||
|
||||
prpl.verifyEvents(
|
||||
ConnectionSetStateEvent(connection, PURPLE_CONNECTED),
|
||||
AddChatEvent(groupChatPurpleName, groupChatTitle, account, nullptr, nullptr),
|
||||
RoomlistAddRoomEvent(superEarlyRoomlist, "id", groupChatPurpleName.c_str()),
|
||||
RoomlistInProgressEvent(superEarlyRoomlist, FALSE),
|
||||
RoomlistAddRoomEvent(earlyRoomlist, "id", groupChatPurpleName.c_str()),
|
||||
RoomlistInProgressEvent(earlyRoomlist, FALSE),
|
||||
AccountSetAliasEvent(account, selfFirstName + " " + selfLastName),
|
||||
ShowAccountEvent(account)
|
||||
);
|
||||
tgl.verifyRequest(getBasicGroupFullInfo(groupId));
|
||||
|
||||
purple_roomlist_unref(superEarlyRoomlist);
|
||||
purple_roomlist_unref(earlyRoomlist);
|
||||
|
||||
PurpleRoomlist *onlineRoomlist = pluginInfo().roomlist_get_list(connection);
|
||||
prpl.verifyEvents(
|
||||
RoomlistInProgressEvent(onlineRoomlist, TRUE),
|
||||
RoomlistAddRoomEvent(onlineRoomlist, "id", groupChatPurpleName.c_str()),
|
||||
RoomlistInProgressEvent(onlineRoomlist, FALSE)
|
||||
);
|
||||
purple_roomlist_unref(onlineRoomlist);
|
||||
}
|
||||
|
@@ -1,3 +1,4 @@
|
||||
#include "libpurple-mock.h"
|
||||
#include "purple-events.h"
|
||||
#include <purple.h>
|
||||
#include <stdarg.h>
|
||||
@@ -716,15 +717,97 @@ void *purple_request_input(void *handle, const char *title, const char *primary,
|
||||
|
||||
PurpleRoomlist *purple_roomlist_new(PurpleAccount *account)
|
||||
{
|
||||
return NULL;
|
||||
PurpleRoomlist *roomlist = new PurpleRoomlist;
|
||||
roomlist->ref = 1;
|
||||
roomlist->ui_data = new RoomlistData;
|
||||
return roomlist;
|
||||
}
|
||||
|
||||
void purple_roomlist_set_in_progress(PurpleRoomlist *list, gboolean in_progress)
|
||||
{
|
||||
EVENT(RoomlistInProgressEvent, list, in_progress);
|
||||
}
|
||||
|
||||
void purple_roomlist_ref(PurpleRoomlist *list)
|
||||
{
|
||||
list->ref++;
|
||||
}
|
||||
|
||||
void purple_roomlist_unref(PurpleRoomlist *list)
|
||||
{
|
||||
ASSERT_NE(0u, list->ref);
|
||||
list->ref--;
|
||||
if (list->ref == 0) {
|
||||
delete static_cast<RoomlistData *>(list->ui_data);
|
||||
delete list;
|
||||
}
|
||||
}
|
||||
|
||||
PurpleRoomlistField *purple_roomlist_field_new(PurpleRoomlistFieldType type,
|
||||
const gchar *label, const gchar *name,
|
||||
gboolean hidden)
|
||||
{
|
||||
PurpleRoomlistField *field = new PurpleRoomlistField;
|
||||
field->type = type;
|
||||
field->name = strdup(name);
|
||||
return field;
|
||||
}
|
||||
|
||||
void purple_roomlist_set_fields(PurpleRoomlist *list, GList *fields)
|
||||
{
|
||||
RoomlistData *fieldStore = static_cast<RoomlistData *>(list->ui_data);
|
||||
for (GList *field = fields; field; field = g_list_next(field)) {
|
||||
PurpleRoomlistField *f = static_cast<PurpleRoomlistField *>(field->data);
|
||||
fieldStore->emplace_back(f->type, f->name);
|
||||
free(f->name);
|
||||
delete f;
|
||||
}
|
||||
g_list_free(fields);
|
||||
}
|
||||
|
||||
struct RealRoom {
|
||||
std::vector<std::string> fieldValues;
|
||||
GList firstField = {NULL, NULL, NULL};
|
||||
};
|
||||
|
||||
PurpleRoomlistRoom *purple_roomlist_room_new(PurpleRoomlistRoomType type, const gchar *name,
|
||||
PurpleRoomlistRoom *parent)
|
||||
{
|
||||
PurpleRoomlistRoom *room = reinterpret_cast<PurpleRoomlistRoom *>(new RealRoom);
|
||||
return room;
|
||||
}
|
||||
|
||||
void purple_roomlist_room_add_field(PurpleRoomlist *list, PurpleRoomlistRoom *notRoom, gconstpointer field)
|
||||
{
|
||||
RoomlistData *fieldList = static_cast<RoomlistData *>(list->ui_data);
|
||||
RealRoom *room = reinterpret_cast<RealRoom *>(notRoom);
|
||||
size_t index = room->fieldValues.size();
|
||||
switch (fieldList->at(index).first) {
|
||||
case PURPLE_ROOMLIST_FIELD_BOOL:
|
||||
room->fieldValues.push_back(field ? "true" : "false");
|
||||
break;
|
||||
case PURPLE_ROOMLIST_FIELD_INT:
|
||||
room->fieldValues.push_back(std::to_string(GPOINTER_TO_INT(field)));
|
||||
break;
|
||||
case PURPLE_ROOMLIST_FIELD_STRING:
|
||||
room->fieldValues.push_back(static_cast<const char *>(field));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GList * purple_roomlist_room_get_fields(PurpleRoomlistRoom *notRoom)
|
||||
{
|
||||
RealRoom *room = reinterpret_cast<RealRoom *>(notRoom);
|
||||
if (!room->fieldValues.empty())
|
||||
room->firstField.data = const_cast<char *>(room->fieldValues[0].c_str());
|
||||
return &room->firstField;
|
||||
}
|
||||
|
||||
void purple_roomlist_room_add(PurpleRoomlist *list, PurpleRoomlistRoom *notRoom)
|
||||
{
|
||||
RealRoom *room = reinterpret_cast<RealRoom *>(notRoom);
|
||||
EVENT(RoomlistAddRoomEvent, list, room->fieldValues);
|
||||
delete room;
|
||||
}
|
||||
|
||||
void purple_serv_got_join_chat_failed(PurpleConnection *gc, GHashTable *data)
|
||||
|
@@ -1,6 +1,11 @@
|
||||
#ifndef _LIBPURPLE_MOCK_H
|
||||
#define _LIBPURPLE_MOCK_H
|
||||
|
||||
#include <glib.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <purple.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
void setFakeFileSize(const char *path, size_t size);
|
||||
@@ -9,5 +14,7 @@ guint8 *arrayDup(gpointer data, size_t size);
|
||||
|
||||
};
|
||||
|
||||
using RoomlistData = std::vector<std::pair<PurpleRoomlistFieldType, std::string>>;
|
||||
|
||||
#endif
|
||||
|
||||
|
@@ -1,4 +1,5 @@
|
||||
#include "purple-events.h"
|
||||
#include "libpurple-mock.h"
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
PurpleEventReceiver g_purpleEvents;
|
||||
@@ -269,6 +270,27 @@ static void compare(const XferRemoteCancelEvent &actual, const XferRemoteCancelE
|
||||
COMPARE(filename);
|
||||
}
|
||||
|
||||
static void compare(const RoomlistInProgressEvent &actual, const RoomlistInProgressEvent &expected)
|
||||
{
|
||||
COMPARE(list);
|
||||
COMPARE(inprogress);
|
||||
}
|
||||
|
||||
static void compare(const RoomlistAddRoomEvent &actual, const RoomlistAddRoomEvent &expected)
|
||||
{
|
||||
COMPARE(roomlist);
|
||||
ASSERT_EQ(nullptr, actual.fieldToCheck);
|
||||
ASSERT_EQ(nullptr, actual.valueToCheck);
|
||||
ASSERT_NE(nullptr, expected.fieldToCheck);
|
||||
ASSERT_NE(nullptr, expected.valueToCheck);
|
||||
|
||||
RoomlistData *fieldList = static_cast<RoomlistData *>(actual.roomlist->ui_data);
|
||||
for (unsigned i = 0; i < fieldList->size(); i++)
|
||||
if (fieldList->at(i).second == expected.fieldToCheck) {
|
||||
ASSERT_EQ(std::string(expected.valueToCheck), actual.fieldValues.at(i));
|
||||
}
|
||||
}
|
||||
|
||||
static void compareEvents(const PurpleEvent &actual, const PurpleEvent &expected)
|
||||
{
|
||||
ASSERT_EQ(expected.type, actual.type) << "Unexpected libpurple event " << actual.toString() <<
|
||||
@@ -316,6 +338,8 @@ static void compareEvents(const PurpleEvent &actual, const PurpleEvent &expected
|
||||
C(XferEnd)
|
||||
C(XferLocalCancel)
|
||||
C(XferRemoteCancel)
|
||||
C(RoomlistInProgress)
|
||||
C(RoomlistAddRoom)
|
||||
default:
|
||||
ASSERT_TRUE(false) << "Unsupported libpurple event " << actual.toString();
|
||||
};
|
||||
@@ -457,6 +481,8 @@ std::string PurpleEvent::toString() const
|
||||
C(XferLocalCancel)
|
||||
C(XferRemoteCancel)
|
||||
C(SetUserPhoto)
|
||||
C(RoomlistInProgress)
|
||||
C(RoomlistAddRoom)
|
||||
}
|
||||
return std::to_string((unsigned)type);
|
||||
#undef C
|
||||
|
@@ -96,7 +96,9 @@ enum class PurpleEventType: uint8_t {
|
||||
XferEnd,
|
||||
XferLocalCancel,
|
||||
XferRemoteCancel,
|
||||
SetUserPhoto
|
||||
SetUserPhoto,
|
||||
RoomlistInProgress,
|
||||
RoomlistAddRoom
|
||||
};
|
||||
|
||||
struct PurpleEvent {
|
||||
@@ -503,4 +505,27 @@ struct SetUserPhotoEvent: PurpleEvent {
|
||||
}
|
||||
};
|
||||
|
||||
struct RoomlistInProgressEvent: PurpleEvent {
|
||||
PurpleRoomlist *list;
|
||||
bool inprogress;
|
||||
|
||||
RoomlistInProgressEvent(PurpleRoomlist *list, bool inprogress)
|
||||
: PurpleEvent(PurpleEventType::RoomlistInProgress), list(list), inprogress(inprogress) {}
|
||||
};
|
||||
|
||||
struct RoomlistAddRoomEvent: PurpleEvent {
|
||||
PurpleRoomlist *roomlist;
|
||||
std::vector<std::string> fieldValues;
|
||||
const char *fieldToCheck = NULL;
|
||||
const char *valueToCheck = NULL;
|
||||
|
||||
RoomlistAddRoomEvent(PurpleRoomlist *roomlist, const std::vector<std::string> &values)
|
||||
: PurpleEvent(PurpleEventType::RoomlistAddRoom), roomlist(roomlist), fieldValues(values) {}
|
||||
|
||||
RoomlistAddRoomEvent(PurpleRoomlist *roomlist, const char *fieldToCheck,
|
||||
const char *valueToCheck)
|
||||
: PurpleEvent(PurpleEventType::RoomlistAddRoom), roomlist(roomlist), fieldToCheck(fieldToCheck),
|
||||
valueToCheck(valueToCheck) {}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user