mirror of
https://gitlab.gnome.org/GNOME/calls.git
synced 2025-01-06 03:25:31 +00:00
tests: Add ringer tests
We mock libfeedback and CallsCall to test the ringer for the following scenarios: - Call state changes - User requested silencing of ringer - Multiple calls
This commit is contained in:
parent
f86162da03
commit
7dadb3c50f
7 changed files with 878 additions and 0 deletions
|
@ -115,4 +115,35 @@ t = executable('util', test_sources,
|
|||
)
|
||||
test('util', t, env: test_env)
|
||||
|
||||
mock_link_args = [ test_link_args,
|
||||
'-Wl,--wrap=lfb_init',
|
||||
'-Wl,--wrap=lfb_uninit',
|
||||
'-Wl,--wrap=lfb_event_set_feedback_profile',
|
||||
'-Wl,--wrap=lfb_event_trigger_feedback_async',
|
||||
'-Wl,--wrap=lfb_event_trigger_feedback_finish',
|
||||
'-Wl,--wrap=lfb_event_end_feedback_async',
|
||||
'-Wl,--wrap=lfb_event_end_feedback_finish',
|
||||
'-Wl,--wrap=calls_contacts_provider_new',
|
||||
]
|
||||
cmocka = dependency ('cmocka', required: false)
|
||||
|
||||
if cmocka.found ()
|
||||
test_sources = [
|
||||
'mock-call.c', 'mock-call.h', 'mock-libfeedback.h',
|
||||
'test-ringer.c'
|
||||
]
|
||||
|
||||
t = executable('ringer', test_sources,
|
||||
c_args : test_cflags,
|
||||
link_args: mock_link_args,
|
||||
pie: true,
|
||||
link_with : [calls_vala, libcalls],
|
||||
dependencies: [calls_deps, cmocka],
|
||||
include_directories : [
|
||||
calls_includes,
|
||||
]
|
||||
)
|
||||
test('ringer', t, env: test_env)
|
||||
endif
|
||||
|
||||
endif
|
||||
|
|
192
tests/mock-call.c
Normal file
192
tests/mock-call.c
Normal file
|
@ -0,0 +1,192 @@
|
|||
/*
|
||||
* Copyright (C) 2021 Purism SPC
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Author: Evangelos Ribeiro Tzaras <devrtz@fortysixandtwo.eu>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "mock-call.h"
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_NAME,
|
||||
PROP_ID,
|
||||
PROP_STATE,
|
||||
PROP_LAST_PROP,
|
||||
};
|
||||
static GParamSpec *props[PROP_LAST_PROP];
|
||||
|
||||
struct _CallsMockCall
|
||||
{
|
||||
CallsCall parent_instance;
|
||||
|
||||
char *id;
|
||||
char *display_name;
|
||||
CallsCallState state;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (CallsMockCall, calls_mock_call, CALLS_TYPE_CALL)
|
||||
|
||||
|
||||
static void
|
||||
calls_mock_call_answer (CallsCall *call)
|
||||
{
|
||||
g_assert (CALLS_IS_MOCK_CALL (call));
|
||||
g_assert_cmpint (calls_call_get_state (call), ==, CALLS_CALL_STATE_INCOMING);
|
||||
|
||||
calls_mock_call_set_state (CALLS_MOCK_CALL (call), CALLS_CALL_STATE_ACTIVE);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
calls_mock_call_hang_up (CallsCall *call)
|
||||
{
|
||||
g_assert (CALLS_IS_MOCK_CALL (call));
|
||||
g_assert_cmpint (calls_call_get_state (call), !=, CALLS_CALL_STATE_DISCONNECTED);
|
||||
|
||||
calls_mock_call_set_state (CALLS_MOCK_CALL (call), CALLS_CALL_STATE_DISCONNECTED);
|
||||
}
|
||||
|
||||
|
||||
static CallsCallState
|
||||
calls_mock_call_get_state (CallsCall *call)
|
||||
{
|
||||
g_assert (CALLS_IS_MOCK_CALL (call));
|
||||
|
||||
return CALLS_MOCK_CALL (call)->state;
|
||||
}
|
||||
|
||||
static void
|
||||
calls_mock_call_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
CallsMockCall *self = CALLS_MOCK_CALL (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_ID:
|
||||
g_value_set_string (value, self->id);
|
||||
break;
|
||||
case PROP_NAME:
|
||||
g_value_set_string (value, self->display_name);
|
||||
break;
|
||||
case PROP_STATE:
|
||||
g_value_set_enum (value, self->state);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
calls_mock_call_finalize (GObject *object)
|
||||
{
|
||||
CallsMockCall *self = CALLS_MOCK_CALL (object);
|
||||
|
||||
g_free (self->id);
|
||||
g_free (self->display_name);
|
||||
|
||||
G_OBJECT_CLASS (calls_mock_call_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
calls_mock_call_class_init (CallsMockCallClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
CallsCallClass *call_class = CALLS_CALL_CLASS (klass);
|
||||
|
||||
call_class->answer = calls_mock_call_answer;
|
||||
call_class->hang_up = calls_mock_call_hang_up;
|
||||
call_class->get_state = calls_mock_call_get_state;
|
||||
|
||||
object_class->get_property = calls_mock_call_get_property;
|
||||
object_class->finalize = calls_mock_call_finalize;
|
||||
|
||||
g_object_class_override_property (object_class,
|
||||
PROP_ID,
|
||||
"id");
|
||||
props[PROP_ID] = g_object_class_find_property (object_class, "id");
|
||||
|
||||
g_object_class_override_property (object_class,
|
||||
PROP_NAME,
|
||||
"name");
|
||||
props[PROP_NAME] = g_object_class_find_property (object_class, "name");
|
||||
|
||||
g_object_class_override_property (object_class,
|
||||
PROP_STATE,
|
||||
"state");
|
||||
props[PROP_STATE] = g_object_class_find_property (object_class, "state");
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
calls_mock_call_init (CallsMockCall *self)
|
||||
{
|
||||
self->display_name = g_strdup ("John Doe");
|
||||
self->id = g_strdup ("0800 1234");
|
||||
self->state = CALLS_CALL_STATE_INCOMING;
|
||||
}
|
||||
|
||||
|
||||
CallsMockCall *
|
||||
calls_mock_call_new (void)
|
||||
{
|
||||
return g_object_new (CALLS_TYPE_MOCK_CALL, NULL);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
calls_mock_call_set_id (CallsMockCall *self,
|
||||
const char *id)
|
||||
{
|
||||
g_return_if_fail (CALLS_IS_MOCK_CALL (self));
|
||||
|
||||
g_free (self->id);
|
||||
self->id = g_strdup (id);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_ID]);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
calls_mock_call_set_name (CallsMockCall *self,
|
||||
const char *name)
|
||||
{
|
||||
g_return_if_fail (CALLS_IS_MOCK_CALL (self));
|
||||
|
||||
g_free (self->display_name);
|
||||
self->display_name = g_strdup (name);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_NAME]);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
calls_mock_call_set_state (CallsMockCall *self,
|
||||
CallsCallState state)
|
||||
{
|
||||
CallsCallState old_state;
|
||||
|
||||
g_return_if_fail (CALLS_IS_MOCK_CALL (self));
|
||||
|
||||
old_state = self->state;
|
||||
if (old_state == state)
|
||||
return;
|
||||
|
||||
self->state = state;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_STATE]);
|
||||
g_signal_emit_by_name (CALLS_CALL (self),
|
||||
"state-changed",
|
||||
state,
|
||||
old_state);
|
||||
}
|
||||
|
30
tests/mock-call.h
Normal file
30
tests/mock-call.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright (C) 2021 Purism SPC
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Author: Evangelos Ribeiro Tzaras <devrtz@fortysixandtwo.eu>
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "calls-call.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CALLS_TYPE_MOCK_CALL (calls_mock_call_get_type())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (CallsMockCall, calls_mock_call, CALLS, MOCK_CALL, CallsCall)
|
||||
|
||||
CallsMockCall *calls_mock_call_new (void);
|
||||
void calls_mock_call_set_id (CallsMockCall *self,
|
||||
const char *id);
|
||||
void calls_mock_call_set_name (CallsMockCall *self,
|
||||
const char *name);
|
||||
void calls_mock_call_set_state (CallsMockCall *self,
|
||||
CallsCallState state);
|
||||
void calls_mock_call_set_inbound (CallsMockCall *self,
|
||||
gboolean inbound);
|
||||
|
||||
G_END_DECLS
|
5
tests/mock-contacts-provider.h
Normal file
5
tests/mock-contacts-provider.h
Normal file
|
@ -0,0 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#include "calls-contacts-provider.h"
|
||||
|
||||
CallsContactsProvider *__wrap_calls_contacts_provider_new (CallsSettings *seetings);
|
28
tests/mock-libfeedback.h
Normal file
28
tests/mock-libfeedback.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
#pragma once
|
||||
|
||||
#define LIBFEEDBACK_USE_UNSTABLE_API
|
||||
|
||||
#include <libfeedback.h>
|
||||
#include <glib.h>
|
||||
|
||||
|
||||
gboolean __wrap_lfb_init (const char *app_id,
|
||||
GError **error);
|
||||
void __wrap_lfb_uninit (void);
|
||||
void __wrap_lfb_event_set_feedback_profile (LfbEvent *self,
|
||||
const char *profile);
|
||||
|
||||
void __wrap_lfb_event_trigger_feedback_async (LfbEvent *self,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
gboolean __wrap_lfb_event_trigger_feedback_finish (LfbEvent *self,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
void __wrap_lfb_event_end_feedback_async (LfbEvent *self,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
gboolean __wrap_lfb_event_end_feedback_finish (LfbEvent *self,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
83
tests/mock/mock-libfeedback.c
Normal file
83
tests/mock/mock-libfeedback.c
Normal file
|
@ -0,0 +1,83 @@
|
|||
#include "mock-libfeedback.h"
|
||||
|
||||
#include <setjmp.h>
|
||||
#include <cmocka.h>
|
||||
|
||||
|
||||
static gboolean
|
||||
on_mock_timeout (gpointer user_data)
|
||||
{
|
||||
GTask *task = user_data;
|
||||
|
||||
g_task_return_boolean (task, TRUE);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
/* could probably also live without mocking/stubbing lfb_{un,}init()
|
||||
* and run under GTestDBus since we're actually only interested
|
||||
* in the feedback trigger and end functions
|
||||
*/
|
||||
gboolean
|
||||
__wrap_lfb_init (const char *app_id,
|
||||
GError **error)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
__wrap_lfb_uninit (void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
__wrap_lfb_event_set_feedback_profile (LfbEvent *self,
|
||||
const char *profile)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
__wrap_lfb_event_trigger_feedback_async (LfbEvent *self,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GTask *trigger_task = g_task_new (self, cancellable, callback, user_data);
|
||||
int mock_time_ms = mock_type (int);
|
||||
gboolean mock_will_be_cancelled = mock_type (gboolean);
|
||||
|
||||
if (!mock_will_be_cancelled)
|
||||
g_timeout_add (mock_time_ms, on_mock_timeout, trigger_task);
|
||||
}
|
||||
|
||||
|
||||
gboolean
|
||||
__wrap_lfb_event_trigger_feedback_finish (LfbEvent *self,
|
||||
GAsyncResult *res,
|
||||
GError **error)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
__wrap_lfb_event_end_feedback_async (LfbEvent *self,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
gboolean
|
||||
__wrap_lfb_event_end_feedback_finish (LfbEvent *self,
|
||||
GAsyncResult *res,
|
||||
GError **error)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
509
tests/test-ringer.c
Normal file
509
tests/test-ringer.c
Normal file
|
@ -0,0 +1,509 @@
|
|||
/*
|
||||
* 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"
|
||||
#include "mock-call.h"
|
||||
#include "mock-libfeedback.h"
|
||||
#include "mock-contacts-provider.h"
|
||||
|
||||
#include <cmocka.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
|
||||
/* mock libfeedback functions */
|
||||
|
||||
static gboolean
|
||||
on_mock_timeout (gpointer user_data)
|
||||
{
|
||||
GTask *task;
|
||||
GCancellable *cancellable;
|
||||
|
||||
if (!G_IS_TASK (user_data))
|
||||
return G_SOURCE_REMOVE;
|
||||
|
||||
task = G_TASK (user_data);
|
||||
cancellable = g_task_get_cancellable (task);
|
||||
|
||||
if (!g_cancellable_is_cancelled (cancellable))
|
||||
g_task_return_boolean (task, TRUE);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
on_check_task_cancelled (gpointer user_data)
|
||||
{
|
||||
GTask *task;
|
||||
|
||||
if (!G_IS_TASK (user_data))
|
||||
return G_SOURCE_REMOVE;
|
||||
|
||||
task = G_TASK (user_data);
|
||||
|
||||
if (g_task_get_completed (task) || g_task_return_error_if_cancelled (task))
|
||||
return G_SOURCE_REMOVE;
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
|
||||
gboolean
|
||||
__wrap_lfb_init (const char *app_id,
|
||||
GError **error)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
__wrap_lfb_uninit (void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
__wrap_lfb_event_set_feedback_profile (LfbEvent *self,
|
||||
const char *profile)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
__wrap_lfb_event_trigger_feedback_async (LfbEvent *self,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GTask *trigger_task = g_task_new (self, cancellable, callback, user_data);
|
||||
int mock_time_ms = mock_type (int);
|
||||
|
||||
g_timeout_add (mock_time_ms, on_mock_timeout, trigger_task);
|
||||
g_idle_add (G_SOURCE_FUNC (on_check_task_cancelled), trigger_task);
|
||||
}
|
||||
|
||||
|
||||
gboolean
|
||||
__wrap_lfb_event_trigger_feedback_finish (LfbEvent *self,
|
||||
GAsyncResult *res,
|
||||
GError **error)
|
||||
{
|
||||
GTask *task = G_TASK (res);
|
||||
gboolean ret;
|
||||
|
||||
ret = g_task_propagate_boolean (task, error);
|
||||
|
||||
g_object_unref (task);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
__wrap_lfb_event_end_feedback_async (LfbEvent *self,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GTask *trigger_task = g_task_new (self, cancellable, callback, user_data);
|
||||
int mock_time_ms = mock_type (int);
|
||||
|
||||
g_timeout_add (mock_time_ms, on_mock_timeout, trigger_task);
|
||||
}
|
||||
|
||||
|
||||
gboolean
|
||||
__wrap_lfb_event_end_feedback_finish (LfbEvent *self,
|
||||
GAsyncResult *res,
|
||||
GError **error)
|
||||
{
|
||||
GTask *task = G_TASK (res);
|
||||
gboolean ret;
|
||||
|
||||
ret = g_task_propagate_boolean (G_TASK (res), error);
|
||||
|
||||
g_object_unref (task);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
CallsContactsProvider *
|
||||
__wrap_calls_contacts_provider_new (CallsSettings *settings)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* add or remove calls */
|
||||
|
||||
static void
|
||||
add_call (CallsManager *manager,
|
||||
CallsMockCall *call)
|
||||
{
|
||||
g_assert (CALLS_IS_MANAGER (manager));
|
||||
g_assert (CALLS_IS_MOCK_CALL (call));
|
||||
|
||||
g_signal_emit_by_name (manager, "call-add", CALLS_CALL (call), NULL);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
remove_call (CallsManager *manager,
|
||||
CallsMockCall *call)
|
||||
{
|
||||
g_assert (CALLS_IS_MANAGER (manager));
|
||||
g_assert (CALLS_IS_MOCK_CALL (call));
|
||||
|
||||
g_signal_emit_by_name (manager, "call-remove", CALLS_CALL (call), NULL);
|
||||
}
|
||||
|
||||
/* TestData setup and tear down */
|
||||
typedef struct {
|
||||
CallsManager *manager;
|
||||
CallsRinger *ringer;
|
||||
CallsMockCall *call_one;
|
||||
CallsMockCall *call_two;
|
||||
GMainLoop *loop;
|
||||
} 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 ();
|
||||
data->call_two = calls_mock_call_new ();
|
||||
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);
|
||||
g_object_unref (data->call_two);
|
||||
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);
|
||||
|
||||
/* delay before completion of __wrap_lfb_event_trigger_feedback_async() */
|
||||
will_return (__wrap_lfb_event_trigger_feedback_async, 10);
|
||||
/* delay before completion of __wrap_lfb_event_end_feedback_async() */
|
||||
will_return (__wrap_lfb_event_end_feedback_async, 10);
|
||||
|
||||
calls_mock_call_set_state (data->call_one, CALLS_CALL_STATE_INCOMING);
|
||||
add_call (data->manager, data->call_one);
|
||||
|
||||
/* main loop will quit in callback of notify::ring */
|
||||
g_main_loop_run (data->loop);
|
||||
|
||||
remove_call (data->manager, data->call_one);
|
||||
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);
|
||||
|
||||
/* delay before completion of __wrap_lfb_event_trigger_feedback_async() */
|
||||
will_return (__wrap_lfb_event_trigger_feedback_async, 10);
|
||||
/* delay before completion of __wrap_lfb_event_end_feedback_async() */
|
||||
will_return (__wrap_lfb_event_end_feedback_async, 10);
|
||||
|
||||
calls_mock_call_set_state (data->call_one, CALLS_CALL_STATE_INCOMING);
|
||||
add_call (data->manager, data->call_one);
|
||||
|
||||
/* main loop will quit in callback of notify::ring */
|
||||
g_main_loop_run (data->loop);
|
||||
|
||||
remove_call (data->manager, data->call_one);
|
||||
assert_false (calls_ringer_get_is_ringing (data->ringer));
|
||||
}
|
||||
|
||||
|
||||
/* t3: test_ringing_hang_up_call_ringer_cancelled */
|
||||
static gboolean
|
||||
t3_on_ringer_timeout (gpointer user_data)
|
||||
{
|
||||
TestData *data = user_data;
|
||||
static guint test_phase = 0;
|
||||
|
||||
assert_false (calls_ringer_get_is_ringing (data->ringer));
|
||||
if (test_phase == 0) {
|
||||
calls_call_hang_up (CALLS_CALL (data->call_one));
|
||||
test_phase++;
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
g_main_loop_quit ((GMainLoop *) data->loop);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
|
||||
/** this test should use cancellable code path by hanging up before
|
||||
* event triggering completes
|
||||
*/
|
||||
static void
|
||||
test_ringing_hang_up_call_ringer_cancelled (void **state)
|
||||
{
|
||||
TestData *data = *state;
|
||||
|
||||
assert_false (calls_ringer_get_is_ringing (data->ringer));
|
||||
|
||||
/* delay before completion of __wrap_lfb_event_trigger_feedback_async() */
|
||||
will_return (__wrap_lfb_event_trigger_feedback_async, 50);
|
||||
|
||||
calls_mock_call_set_state (data->call_one, CALLS_CALL_STATE_INCOMING);
|
||||
add_call (data->manager, data->call_one);
|
||||
|
||||
g_timeout_add (10, G_SOURCE_FUNC (t3_on_ringer_timeout), data);
|
||||
|
||||
/* main loop will quit in t3_on_ringer_timeout() */
|
||||
g_main_loop_run (data->loop);
|
||||
|
||||
remove_call (data->manager, data->call_one);
|
||||
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));
|
||||
calls_call_silence_ring (CALLS_CALL (data->call_one));
|
||||
assert_true (calls_call_get_silenced (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_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);
|
||||
|
||||
/* delay before completion of __wrap_lfb_event_trigger_feedback_async() */
|
||||
will_return (__wrap_lfb_event_trigger_feedback_async, 10);
|
||||
/* delay before completion of __wrap_lfb_event_end_feedback_async() */
|
||||
will_return (__wrap_lfb_event_end_feedback_async, 10);
|
||||
|
||||
calls_mock_call_set_state (data->call_one, CALLS_CALL_STATE_INCOMING);
|
||||
add_call (data->manager, data->call_one);
|
||||
|
||||
/* main loop will quit in callback of notify::ring */
|
||||
g_main_loop_run (data->loop);
|
||||
|
||||
remove_call (data->manager, data->call_one);
|
||||
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) {
|
||||
remove_call (data->manager, data->call_one);
|
||||
test_phase++;
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
assert_true (calls_ringer_get_is_ringing (data->ringer));
|
||||
remove_call (data->manager, data->call_two);
|
||||
|
||||
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));
|
||||
add_call (data->manager, data->call_two);
|
||||
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);
|
||||
|
||||
/* delay before completion of __wrap_lfb_event_trigger_feedback_async() */
|
||||
will_return (__wrap_lfb_event_trigger_feedback_async, 10);
|
||||
/* delay before completion of __wrap_lfb_event_end_feedback_async() */
|
||||
will_return (__wrap_lfb_event_end_feedback_async, 10);
|
||||
|
||||
calls_mock_call_set_state (data->call_one, CALLS_CALL_STATE_INCOMING);
|
||||
add_call (data->manager, data->call_one);
|
||||
|
||||
/* main loop will quit in callback of notify::ring */
|
||||
g_main_loop_run (data->loop);
|
||||
|
||||
assert_false (calls_ringer_get_is_ringing (data->ringer));
|
||||
}
|
||||
|
||||
|
||||
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_hang_up_call_ringer_cancelled,
|
||||
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),
|
||||
};
|
||||
|
||||
return cmocka_run_group_tests (tests, NULL, NULL);
|
||||
}
|
||||
|
Loading…
Reference in a new issue