Files
cproof/tests/functionaltests/test_presence.c
Michael Vetter 9cb11bdec2 tests: Reenable functional tests
They were disabled in 171b6e73c9.

Enable the functional test suite and replaces the
dependency on libexpect with a custom solution.

The native solution allows for specific optimizations like automatic
ANSI code stripping, which is essential for reliable pattern matching in
an ncurses interface.

Custom PTY management via libutil provides full control over the process
lifecycle, resolving issues where tests would hang indefinitely.
We use forkpty from libutil.

Addiiotnally this commit implements automatic ANSI escape sequence
filtering to improve matching consistency.
This will get rid of the colors in matches. It's still something that we
need to think about more since basically we will not test out
color/theme system this way.

We also add non-blocking poll() and SIGKILL based teardown logic to
ensure clean test termination.

We added the functional tests to both autotools and meson.
They are only build when tests are enabled and stabber + libutil are
present.
Meson will print this out nicely in the summary.

Regards https://github.com/profanity-im/profanity/issues/789
2026-03-04 22:32:38 +01:00

270 lines
7.3 KiB
C

#include <glib.h>
#include "prof_cmocka.h"
#include <stdlib.h>
#include <string.h>
#include <stabber.h>
#include "proftest.h"
void
presence_online(void** state)
{
prof_connect();
prof_input("/online");
assert_true(stbbr_received(
"<presence id='prof_presence_*'>"
"<c hash='sha-1' xmlns='http://jabber.org/protocol/caps' ver='*' node='http://profanity-im.github.io'/>"
"</presence>"));
assert_true(prof_output_exact("Status set to online (priority 0)"));
}
void
presence_online_with_message(void** state)
{
prof_connect();
prof_input("/online \"Hi there\"");
assert_true(stbbr_received(
"<presence id='prof_presence_*'>"
"<status>Hi there</status>"
"<c hash='sha-1' xmlns='http://jabber.org/protocol/caps' ver='*' node='http://profanity-im.github.io'/>"
"</presence>"));
assert_true(prof_output_exact("Status set to online (priority 0), \"Hi there\"."));
}
void
presence_away(void** state)
{
prof_connect();
prof_input("/away");
assert_true(stbbr_received(
"<presence id='prof_presence_*'>"
"<show>away</show>"
"<c hash='sha-1' xmlns='http://jabber.org/protocol/caps' ver='*' node='http://profanity-im.github.io'/>"
"</presence>"));
assert_true(prof_output_exact("Status set to away (priority 0)"));
}
void
presence_away_with_message(void** state)
{
prof_connect();
prof_input("/away \"I'm not here for a bit\"");
assert_true(stbbr_received(
"<presence id='prof_presence_*'>"
"<show>away</show>"
"<status>I'm not here for a bit</status>"
"<c hash='sha-1' xmlns='http://jabber.org/protocol/caps' ver='*' node='http://profanity-im.github.io'/>"
"</presence>"));
assert_true(prof_output_exact("Status set to away (priority 0), \"I'm not here for a bit\"."));
}
void
presence_xa(void** state)
{
prof_connect();
prof_input("/xa");
assert_true(stbbr_received(
"<presence id='prof_presence_*'>"
"<show>xa</show>"
"<c hash='sha-1' xmlns='http://jabber.org/protocol/caps' ver='*' node='http://profanity-im.github.io'/>"
"</presence>"));
assert_true(prof_output_exact("Status set to xa (priority 0)"));
}
void
presence_xa_with_message(void** state)
{
prof_connect();
prof_input("/xa \"Gone to the shops\"");
assert_true(stbbr_received(
"<presence id='prof_presence_*'>"
"<show>xa</show>"
"<status>Gone to the shops</status>"
"<c hash='sha-1' xmlns='http://jabber.org/protocol/caps' ver='*' node='http://profanity-im.github.io'/>"
"</presence>"));
assert_true(prof_output_exact("Status set to xa (priority 0), \"Gone to the shops\"."));
}
void
presence_dnd(void** state)
{
prof_connect();
prof_input("/dnd");
assert_true(stbbr_received(
"<presence id='prof_presence_*'>"
"<show>dnd</show>"
"<c hash='sha-1' xmlns='http://jabber.org/protocol/caps' ver='*' node='http://profanity-im.github.io'/>"
"</presence>"));
assert_true(prof_output_exact("Status set to dnd (priority 0)"));
}
void
presence_dnd_with_message(void** state)
{
prof_connect();
prof_input("/dnd \"Working\"");
assert_true(stbbr_received(
"<presence id='prof_presence_*'>"
"<show>dnd</show>"
"<status>Working</status>"
"<c hash='sha-1' xmlns='http://jabber.org/protocol/caps' ver='*' node='http://profanity-im.github.io'/>"
"</presence>"));
assert_true(prof_output_exact("Status set to dnd (priority 0), \"Working\"."));
}
void
presence_chat(void** state)
{
prof_connect();
prof_input("/chat");
assert_true(stbbr_received(
"<presence id='prof_presence_*'>"
"<show>chat</show>"
"<c hash='sha-1' xmlns='http://jabber.org/protocol/caps' ver='*' node='http://profanity-im.github.io'/>"
"</presence>"));
assert_true(prof_output_exact("Status set to chat (priority 0)"));
}
void
presence_chat_with_message(void** state)
{
prof_connect();
prof_input("/chat \"Free to talk\"");
assert_true(stbbr_received(
"<presence id='prof_presence_*'>"
"<show>chat</show>"
"<status>Free to talk</status>"
"<c hash='sha-1' xmlns='http://jabber.org/protocol/caps' ver='*' node='http://profanity-im.github.io'/>"
"</presence>"));
assert_true(prof_output_exact("Status set to chat (priority 0), \"Free to talk\"."));
}
void
presence_set_priority(void** state)
{
prof_connect();
prof_input("/priority 25");
assert_true(stbbr_received(
"<presence id='prof_presence_*'>"
"<priority>25</priority>"
"<c hash='sha-1' xmlns='http://jabber.org/protocol/caps' ver='*' node='http://profanity-im.github.io'/>"
"</presence>"));
assert_true(prof_output_exact("Priority set to 25."));
}
void
presence_includes_priority(void** state)
{
prof_connect();
prof_input("/priority 25");
assert_true(stbbr_received(
"<presence id='prof_presence_*'>"
"<priority>25</priority>"
"<c hash='sha-1' xmlns='http://jabber.org/protocol/caps' ver='*' node='http://profanity-im.github.io'/>"
"</presence>"));
assert_true(prof_output_exact("Priority set to 25."));
prof_input("/chat \"Free to talk\"");
assert_true(stbbr_received(
"<presence id='prof_presence_*'>"
"<priority>25</priority>"
"<show>chat</show>"
"<status>Free to talk</status>"
"<c hash='sha-1' xmlns='http://jabber.org/protocol/caps' ver='*' node='http://profanity-im.github.io'/>"
"</presence>"));
assert_true(prof_output_exact("Status set to chat (priority 25), \"Free to talk\"."));
}
void
presence_keeps_status(void** state)
{
prof_connect();
prof_input("/chat \"Free to talk\"");
assert_true(stbbr_received(
"<presence id='prof_presence_*'>"
"<show>chat</show>"
"<status>Free to talk</status>"
"<c hash='sha-1' xmlns='http://jabber.org/protocol/caps' ver='*' node='http://profanity-im.github.io'/>"
"</presence>"));
assert_true(prof_output_exact("Status set to chat (priority 0), \"Free to talk\"."));
prof_input("/priority 25");
assert_true(stbbr_received(
"<presence id='prof_presence_*'>"
"<show>chat</show>"
"<status>Free to talk</status>"
"<priority>25</priority>"
"<c hash='sha-1' xmlns='http://jabber.org/protocol/caps' ver='*' node='http://profanity-im.github.io'/>"
"</presence>"));
assert_true(prof_output_exact("Priority set to 25."));
}
void
presence_received(void** state)
{
prof_connect();
stbbr_send(
"<presence to='stabber@localhost' from='buddy1@localhost/mobile'>"
"<priority>10</priority>"
"<status>I'm here</status>"
"</presence>");
assert_true(prof_output_exact("Buddy1 (mobile) is online, \"I'm here\""));
}
// Typical use case for gateways that don't support resources
void
presence_missing_resource_defaults(void** state)
{
prof_connect();
stbbr_send(
"<presence to='stabber@localhost' from='buddy1@localhost'>"
"<priority>15</priority>"
"<status>My status</status>"
"</presence>");
assert_true(prof_output_exact("Buddy1 is online, \"My status\""));
prof_input("/info Buddy1");
assert_true(prof_output_exact("__prof_default (15), online"));
}