2021-10-22 05:23:29 +00:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2021 Purism SPC
|
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
*
|
|
|
|
* Author: Evangelos Ribeiro Tzaras <devrtz@fortysixandtwo.eu>
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "calls-manager.h"
|
|
|
|
#include "calls-ringer.h"
|
2022-01-31 16:18:35 +00:00
|
|
|
#include "calls-ui-call-data.h"
|
2021-10-22 05:23:29 +00:00
|
|
|
#include "mock-call.h"
|
|
|
|
#include "mock-libfeedback.h"
|
|
|
|
#include "mock-contacts-provider.h"
|
|
|
|
|
|
|
|
#include <cmocka.h>
|
|
|
|
#include <setjmp.h>
|
|
|
|
|
|
|
|
|
2022-09-19 16:50:53 +00:00
|
|
|
/* mock calls_contacts_provider_new() */
|
2021-10-22 05:23:29 +00:00
|
|
|
CallsContactsProvider *
|
2022-05-09 20:57:41 +00:00
|
|
|
__wrap_calls_contacts_provider_new (void)
|
2021-10-22 05:23:29 +00:00
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* add or remove calls */
|
|
|
|
|
|
|
|
static void
|
2022-01-31 16:18:35 +00:00
|
|
|
add_call (CallsManager *manager,
|
|
|
|
CallsUiCallData *call)
|
2021-10-22 05:23:29 +00:00
|
|
|
{
|
|
|
|
g_assert (CALLS_IS_MANAGER (manager));
|
2022-01-31 16:18:35 +00:00
|
|
|
g_assert (CALLS_IS_UI_CALL_DATA (call));
|
2021-10-22 05:23:29 +00:00
|
|
|
|
2022-01-31 16:18:35 +00:00
|
|
|
g_signal_emit_by_name (manager, "ui-call-added", call, NULL);
|
2021-10-22 05:23:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
2022-01-31 16:18:35 +00:00
|
|
|
remove_call (CallsManager *manager,
|
|
|
|
CallsUiCallData *call)
|
2021-10-22 05:23:29 +00:00
|
|
|
{
|
|
|
|
g_assert (CALLS_IS_MANAGER (manager));
|
2022-01-31 16:18:35 +00:00
|
|
|
g_assert (CALLS_IS_UI_CALL_DATA (call));
|
2021-10-22 05:23:29 +00:00
|
|
|
|
2022-01-31 16:18:35 +00:00
|
|
|
g_signal_emit_by_name (manager, "ui-call-removed", call, NULL);
|
2021-10-22 05:23:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* TestData setup and tear down */
|
|
|
|
typedef struct {
|
2022-01-31 16:18:35 +00:00
|
|
|
CallsManager *manager;
|
|
|
|
CallsRinger *ringer;
|
|
|
|
CallsMockCall *call_one;
|
|
|
|
CallsUiCallData *ui_call_one;
|
|
|
|
CallsMockCall *call_two;
|
|
|
|
CallsUiCallData *ui_call_two;
|
|
|
|
GMainLoop *loop;
|
2021-10-22 05:23:29 +00:00
|
|
|
} TestData;
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
setup_test_data (void **state)
|
|
|
|
{
|
|
|
|
TestData *data = g_new0 (TestData, 1);
|
|
|
|
|
|
|
|
if (data == NULL)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
data->manager = calls_manager_get_default ();
|
|
|
|
data->ringer = calls_ringer_new ();
|
|
|
|
data->call_one = calls_mock_call_new ();
|
2022-02-03 17:52:52 +00:00
|
|
|
data->ui_call_one = calls_ui_call_data_new (CALLS_CALL (data->call_one), NULL);
|
2021-10-22 05:23:29 +00:00
|
|
|
data->call_two = calls_mock_call_new ();
|
2022-02-03 17:52:52 +00:00
|
|
|
data->ui_call_two = calls_ui_call_data_new (CALLS_CALL (data->call_two), NULL);
|
2021-10-22 05:23:29 +00:00
|
|
|
data->loop = g_main_loop_new (NULL, FALSE);
|
|
|
|
|
|
|
|
*state = data;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
tear_down_test_data (void **state)
|
|
|
|
{
|
|
|
|
TestData *data = *state;
|
|
|
|
|
|
|
|
g_object_unref (data->call_one);
|
2022-01-31 16:18:35 +00:00
|
|
|
g_object_unref (data->ui_call_one);
|
2021-10-22 05:23:29 +00:00
|
|
|
g_object_unref (data->call_two);
|
2022-01-31 16:18:35 +00:00
|
|
|
g_object_unref (data->ui_call_two);
|
2021-10-22 05:23:29 +00:00
|
|
|
g_object_unref (data->ringer);
|
|
|
|
g_main_loop_unref (data->loop);
|
|
|
|
|
|
|
|
g_free (data);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* t1: test_ringing_incoming_call */
|
|
|
|
static void
|
|
|
|
t1_on_ringer_call_accepted (CallsRinger *ringer,
|
|
|
|
GParamSpec *pspec,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
static guint test_phase = 0;
|
|
|
|
TestData *data = user_data;
|
|
|
|
|
|
|
|
switch (test_phase++) {
|
|
|
|
case 0: /* incoming call */
|
|
|
|
assert_true (calls_ringer_get_is_ringing (ringer));
|
|
|
|
calls_call_answer (CALLS_CALL (data->call_one));
|
|
|
|
break;
|
|
|
|
case 1: /* incoming call accepted */
|
|
|
|
assert_false (calls_ringer_get_is_ringing (ringer));
|
|
|
|
g_main_loop_quit ((GMainLoop *) data->loop);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
g_assert_not_reached (); /* did not find equivalent cmocka assertion */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_ringing_accept_call (void **state)
|
|
|
|
{
|
|
|
|
TestData *data = *state;
|
|
|
|
|
|
|
|
assert_false (calls_ringer_get_is_ringing (data->ringer));
|
|
|
|
|
|
|
|
g_signal_connect (data->ringer,
|
|
|
|
"notify::ringing",
|
|
|
|
G_CALLBACK (t1_on_ringer_call_accepted),
|
|
|
|
data);
|
|
|
|
|
2021-12-10 08:02:39 +00:00
|
|
|
calls_call_set_state (CALLS_CALL (data->call_one), CALLS_CALL_STATE_INCOMING);
|
2022-01-31 16:18:35 +00:00
|
|
|
add_call (data->manager, data->ui_call_one);
|
2021-10-22 05:23:29 +00:00
|
|
|
|
|
|
|
/* main loop will quit in callback of notify::ring */
|
|
|
|
g_main_loop_run (data->loop);
|
|
|
|
|
2022-01-31 16:18:35 +00:00
|
|
|
remove_call (data->manager, data->ui_call_one);
|
2021-10-22 05:23:29 +00:00
|
|
|
assert_false (calls_ringer_get_is_ringing (data->ringer));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* t2: test_ringing_hang_up_call */
|
|
|
|
static void
|
|
|
|
t2_on_ringer_call_hang_up (CallsRinger *ringer,
|
|
|
|
GParamSpec *pspec,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
static guint test_phase = 0;
|
|
|
|
TestData *data = user_data;
|
|
|
|
|
|
|
|
switch (test_phase++) {
|
|
|
|
case 0: /* incoming call */
|
|
|
|
assert_true (calls_ringer_get_is_ringing (ringer));
|
|
|
|
calls_call_hang_up (CALLS_CALL (data->call_one));
|
|
|
|
break;
|
|
|
|
case 1: /* incoming call hung up */
|
|
|
|
assert_false (calls_ringer_get_is_ringing (ringer));
|
|
|
|
g_main_loop_quit ((GMainLoop *) data->loop);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
g_assert_not_reached (); /* did not find equivalent cmocka assertion */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_ringing_hang_up_call (void **state)
|
|
|
|
{
|
|
|
|
TestData *data = *state;
|
|
|
|
|
|
|
|
assert_false (calls_ringer_get_is_ringing (data->ringer));
|
|
|
|
|
|
|
|
g_signal_connect (data->ringer,
|
|
|
|
"notify::ringing",
|
|
|
|
G_CALLBACK (t2_on_ringer_call_hang_up),
|
|
|
|
data);
|
|
|
|
|
2021-12-10 08:02:39 +00:00
|
|
|
calls_call_set_state (CALLS_CALL (data->call_one), CALLS_CALL_STATE_INCOMING);
|
2022-01-31 16:18:35 +00:00
|
|
|
add_call (data->manager, data->ui_call_one);
|
2021-10-22 05:23:29 +00:00
|
|
|
|
|
|
|
/* main loop will quit in callback of notify::ring */
|
|
|
|
g_main_loop_run (data->loop);
|
|
|
|
|
2022-01-31 16:18:35 +00:00
|
|
|
remove_call (data->manager, data->ui_call_one);
|
2021-10-22 05:23:29 +00:00
|
|
|
assert_false (calls_ringer_get_is_ringing (data->ringer));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* t4: test_ringing_silence_call */
|
|
|
|
static void
|
|
|
|
t4_on_ringer_call_silence (CallsRinger *ringer,
|
|
|
|
GParamSpec *pspec,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
static guint test_phase = 0;
|
|
|
|
TestData *data = user_data;
|
|
|
|
|
|
|
|
switch (test_phase++) {
|
|
|
|
case 0: /* incoming call */
|
|
|
|
assert_true (calls_ringer_get_is_ringing (ringer));
|
2022-01-31 16:18:35 +00:00
|
|
|
calls_ui_call_data_silence_ring (data->ui_call_one);
|
|
|
|
assert_true (calls_ui_call_data_get_silenced (data->ui_call_one));
|
2021-10-22 05:23:29 +00:00
|
|
|
break;
|
|
|
|
case 1: /* incoming call hung up */
|
|
|
|
assert_false (calls_ringer_get_is_ringing (ringer));
|
|
|
|
g_main_loop_quit ((GMainLoop *) data->loop);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
g_assert_not_reached (); /* did not find equivalent cmocka assertion */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_ringing_silence_call (void **state)
|
|
|
|
{
|
|
|
|
TestData *data = *state;
|
|
|
|
|
|
|
|
assert_false (calls_ringer_get_is_ringing (data->ringer));
|
|
|
|
|
|
|
|
g_signal_connect (data->ringer,
|
|
|
|
"notify::ringing",
|
|
|
|
G_CALLBACK (t4_on_ringer_call_silence),
|
|
|
|
data);
|
|
|
|
|
2021-12-10 08:02:39 +00:00
|
|
|
calls_call_set_state (CALLS_CALL (data->call_one), CALLS_CALL_STATE_INCOMING);
|
2022-01-31 16:18:35 +00:00
|
|
|
add_call (data->manager, data->ui_call_one);
|
2021-10-22 05:23:29 +00:00
|
|
|
|
|
|
|
/* main loop will quit in callback of notify::ring */
|
|
|
|
g_main_loop_run (data->loop);
|
|
|
|
|
2022-01-31 16:18:35 +00:00
|
|
|
remove_call (data->manager, data->ui_call_one);
|
2021-10-22 05:23:29 +00:00
|
|
|
assert_false (calls_ringer_get_is_ringing (data->ringer));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* t5: test_ringing_multiple_call */
|
|
|
|
static gboolean
|
|
|
|
t5_remove_calls (gpointer user_data)
|
|
|
|
{
|
|
|
|
static guint test_phase = 0;
|
|
|
|
TestData *data = user_data;
|
|
|
|
|
|
|
|
if (test_phase == 0) {
|
2022-01-31 16:18:35 +00:00
|
|
|
remove_call (data->manager, data->ui_call_one);
|
2021-10-22 05:23:29 +00:00
|
|
|
test_phase++;
|
|
|
|
return G_SOURCE_CONTINUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
assert_true (calls_ringer_get_is_ringing (data->ringer));
|
2022-01-31 16:18:35 +00:00
|
|
|
remove_call (data->manager, data->ui_call_two);
|
2021-10-22 05:23:29 +00:00
|
|
|
|
|
|
|
return G_SOURCE_REMOVE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
t5_on_ringer_multiple_calls (CallsRinger *ringer,
|
|
|
|
GParamSpec *pspec,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
static guint test_phase = 0;
|
|
|
|
TestData *data = user_data;
|
|
|
|
|
|
|
|
switch (test_phase++) {
|
|
|
|
case 0: /* add second call, and schedule call removal */
|
|
|
|
assert_true (calls_ringer_get_is_ringing (ringer));
|
2022-01-31 16:18:35 +00:00
|
|
|
add_call (data->manager, data->ui_call_two);
|
2021-10-22 05:23:29 +00:00
|
|
|
g_timeout_add (25, t5_remove_calls, data);
|
|
|
|
break;
|
|
|
|
case 1: /* both calls should be removed now */
|
|
|
|
assert_false (calls_ringer_get_is_ringing (ringer));
|
|
|
|
g_main_loop_quit ((GMainLoop *) data->loop);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
g_assert_not_reached (); /* did not find equivalent cmocka assertion */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_ringing_multiple_calls (void **state)
|
|
|
|
{
|
|
|
|
TestData *data = *state;
|
|
|
|
|
|
|
|
assert_false (calls_ringer_get_is_ringing (data->ringer));
|
|
|
|
|
|
|
|
g_signal_connect (data->ringer,
|
|
|
|
"notify::ringing",
|
|
|
|
G_CALLBACK (t5_on_ringer_multiple_calls),
|
|
|
|
data);
|
|
|
|
|
2021-12-10 08:02:39 +00:00
|
|
|
calls_call_set_state (CALLS_CALL (data->call_one), CALLS_CALL_STATE_INCOMING);
|
2022-01-31 16:18:35 +00:00
|
|
|
add_call (data->manager, data->ui_call_one);
|
2021-10-22 05:23:29 +00:00
|
|
|
|
|
|
|
/* main loop will quit in callback of notify::ring */
|
|
|
|
g_main_loop_run (data->loop);
|
|
|
|
|
|
|
|
assert_false (calls_ringer_get_is_ringing (data->ringer));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-11-26 07:41:22 +00:00
|
|
|
static void
|
|
|
|
t6_on_ringer_multiple_calls_with_restart (CallsRinger *ringer,
|
|
|
|
GParamSpec *pspec,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
static guint test_phase = 0;
|
|
|
|
TestData *data = user_data;
|
|
|
|
|
|
|
|
switch (test_phase++) {
|
|
|
|
case 0:
|
|
|
|
assert_true (calls_ringer_get_is_ringing (ringer));
|
|
|
|
assert_false (calls_ringer_get_ring_is_quiet (ringer));
|
|
|
|
|
|
|
|
calls_call_answer (CALLS_CALL (data->call_one));
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
assert_true (calls_ringer_get_is_ringing (ringer));
|
|
|
|
assert_true (calls_ringer_get_ring_is_quiet (ringer));
|
|
|
|
|
|
|
|
calls_call_hang_up (CALLS_CALL (data->call_one));
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
assert_true (calls_ringer_get_is_ringing (ringer));
|
|
|
|
assert_false (calls_ringer_get_ring_is_quiet (ringer));
|
|
|
|
|
|
|
|
calls_call_hang_up (CALLS_CALL (data->call_two));
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
assert_false (calls_ringer_get_is_ringing (ringer));
|
|
|
|
assert_false (calls_ringer_get_ring_is_quiet (ringer));
|
|
|
|
|
|
|
|
g_main_loop_quit (data->loop);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
g_assert_not_reached (); /* did not find equivalent cmocka assertion */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_ringing_multiple_calls_with_restart (void **state)
|
|
|
|
{
|
|
|
|
TestData *data = *state;
|
|
|
|
|
|
|
|
assert_false (calls_ringer_get_is_ringing (data->ringer));
|
|
|
|
|
|
|
|
g_signal_connect (data->ringer,
|
|
|
|
"notify::ringing",
|
|
|
|
G_CALLBACK (t6_on_ringer_multiple_calls_with_restart),
|
|
|
|
data);
|
|
|
|
|
2021-12-10 08:02:39 +00:00
|
|
|
calls_call_set_state (CALLS_CALL (data->call_one), CALLS_CALL_STATE_INCOMING);
|
2022-01-31 16:18:35 +00:00
|
|
|
add_call (data->manager, data->ui_call_one);
|
2021-12-10 08:02:39 +00:00
|
|
|
calls_call_set_state (CALLS_CALL (data->call_two), CALLS_CALL_STATE_INCOMING);
|
2022-01-31 16:18:35 +00:00
|
|
|
add_call (data->manager, data->ui_call_two);
|
2021-11-26 07:41:22 +00:00
|
|
|
|
|
|
|
/* main loop will quit in callback of notify::ring */
|
|
|
|
g_main_loop_run (data->loop);
|
|
|
|
|
|
|
|
assert_false (calls_ringer_get_is_ringing (data->ringer));
|
|
|
|
}
|
|
|
|
|
2021-10-22 05:23:29 +00:00
|
|
|
int
|
|
|
|
main (int argc,
|
|
|
|
char *argv[])
|
|
|
|
{
|
|
|
|
const struct CMUnitTest tests[] = {
|
|
|
|
cmocka_unit_test_setup_teardown (test_ringing_accept_call,
|
|
|
|
setup_test_data,
|
|
|
|
tear_down_test_data),
|
|
|
|
cmocka_unit_test_setup_teardown (test_ringing_hang_up_call,
|
|
|
|
setup_test_data,
|
|
|
|
tear_down_test_data),
|
|
|
|
cmocka_unit_test_setup_teardown (test_ringing_silence_call,
|
|
|
|
setup_test_data,
|
|
|
|
tear_down_test_data),
|
|
|
|
cmocka_unit_test_setup_teardown (test_ringing_multiple_calls,
|
|
|
|
setup_test_data,
|
|
|
|
tear_down_test_data),
|
2021-11-26 07:41:22 +00:00
|
|
|
cmocka_unit_test_setup_teardown (test_ringing_multiple_calls_with_restart,
|
|
|
|
setup_test_data,
|
|
|
|
tear_down_test_data)
|
2021-10-22 05:23:29 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
return cmocka_run_group_tests (tests, NULL, NULL);
|
|
|
|
}
|
|
|
|
|