1 /* Feature test for Conn.I.Balance
2 *
3 * Copyright © 2007-2011 Collabora Ltd. <http://www.collabora.co.uk/>
4 * Copyright © 2007-2008 Nokia Corporation
5 *
6 * Copying and distribution of this file, with or without modification,
7 * are permitted in any medium without royalty provided the copyright
8 * notice and this notice are preserved.
9 */
10
11 #include "config.h"
12
13 #include <telepathy-glib/connection.h>
14 #include <telepathy-glib/dbus.h>
15 #include <telepathy-glib/debug.h>
16 #include <telepathy-glib/interfaces.h>
17 #include <telepathy-glib/proxy-subclass.h>
18
19 #include <dbus/dbus-glib.h>
20 #include <dbus/dbus-glib-lowlevel.h>
21
22 #include "tests/lib/simple-conn.h"
23 #include "tests/lib/util.h"
24
25 #define BALANCE 1234
26 #define BALANCE_SCALE 2
27 #define BALANCE_CURRENCY "BDD" /* badger dollars */
28 #define MANAGE_CREDIT_URI "http://chat.badger.net/topup"
29
30 /* -- BalancedConnection -- */
31 typedef TpTestsSimpleConnection BalancedConnection;
32 typedef TpTestsSimpleConnectionClass BalancedConnectionClass;
33
34 #define TYPE_BALANCED_CONNECTION (balanced_connection_get_type ())
35 static GType balanced_connection_get_type (void);
36
37 G_DEFINE_TYPE_WITH_CODE (BalancedConnection,
38 balanced_connection,
39 TP_TESTS_TYPE_SIMPLE_CONNECTION,
40
41 G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_BALANCE, NULL))
42
43 enum
44 {
45 PROP_0,
46 PROP_ACCOUNT_BALANCE,
47 PROP_MANAGE_CREDIT_URI
48 };
49
50 static void
balanced_connection_get_property(GObject * self G_GNUC_UNUSED,guint prop_id,GValue * value,GParamSpec * pspec)51 balanced_connection_get_property (GObject *self G_GNUC_UNUSED,
52 guint prop_id,
53 GValue *value,
54 GParamSpec *pspec)
55 {
56 switch (prop_id)
57 {
58 case PROP_ACCOUNT_BALANCE:
59 /* known balance */
60 g_value_take_boxed (value, tp_value_array_build (3,
61 G_TYPE_INT, BALANCE,
62 G_TYPE_UINT, BALANCE_SCALE,
63 G_TYPE_STRING, BALANCE_CURRENCY,
64 G_TYPE_INVALID));
65 break;
66
67 case PROP_MANAGE_CREDIT_URI:
68 g_value_set_static_string (value, MANAGE_CREDIT_URI);
69 break;
70
71 default:
72 G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec);
73 break;
74 }
75 }
76
77 static void
balanced_connection_init(BalancedConnection * self G_GNUC_UNUSED)78 balanced_connection_init (BalancedConnection *self G_GNUC_UNUSED)
79 {
80 }
81
82 static GPtrArray *
get_interfaces(TpBaseConnection * base)83 get_interfaces (TpBaseConnection *base)
84 {
85 GPtrArray *interfaces;
86
87 interfaces = TP_BASE_CONNECTION_CLASS (
88 balanced_connection_parent_class)->get_interfaces_always_present (base);
89
90 g_ptr_array_add (interfaces, TP_IFACE_CONNECTION_INTERFACE_BALANCE);
91
92 return interfaces;
93 }
94
95 static void
balanced_connection_class_init(BalancedConnectionClass * cls)96 balanced_connection_class_init (BalancedConnectionClass *cls)
97 {
98 GObjectClass *object_class = (GObjectClass *) cls;
99 TpBaseConnectionClass *base_class = TP_BASE_CONNECTION_CLASS (cls);
100
101 static TpDBusPropertiesMixinPropImpl balance_props[] = {
102 { "AccountBalance", "account-balance", NULL },
103 { "ManageCreditURI", "manage-credit-uri", NULL },
104 { NULL }
105 };
106
107 object_class->get_property = balanced_connection_get_property;
108
109 base_class->get_interfaces_always_present = get_interfaces;
110
111 g_object_class_install_property (object_class, PROP_ACCOUNT_BALANCE,
112 g_param_spec_boxed ("account-balance", "", "",
113 TP_STRUCT_TYPE_CURRENCY_AMOUNT,
114 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
115
116 g_object_class_install_property (object_class, PROP_MANAGE_CREDIT_URI,
117 g_param_spec_string ("manage-credit-uri", "", "",
118 NULL,
119 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
120
121 tp_dbus_properties_mixin_implement_interface (object_class,
122 TP_IFACE_QUARK_CONNECTION_INTERFACE_BALANCE,
123 tp_dbus_properties_mixin_getter_gobject_properties, NULL,
124 balance_props);
125 }
126
127 /* -- UnbalancedConnection -- */
128 typedef TpTestsSimpleConnection UnbalancedConnection;
129 typedef TpTestsSimpleConnectionClass UnbalancedConnectionClass;
130
131 #define TYPE_UNBALANCED_CONNECTION (unbalanced_connection_get_type ())
132 static GType unbalanced_connection_get_type (void);
133
G_DEFINE_TYPE(UnbalancedConnection,unbalanced_connection,TYPE_BALANCED_CONNECTION)134 G_DEFINE_TYPE (UnbalancedConnection,
135 unbalanced_connection,
136 TYPE_BALANCED_CONNECTION)
137
138 static void
139 unbalanced_connection_get_property (GObject *self G_GNUC_UNUSED,
140 guint prop_id,
141 GValue *value,
142 GParamSpec *pspec)
143 {
144 switch (prop_id)
145 {
146 case PROP_ACCOUNT_BALANCE:
147 /* unknown balance */
148 g_value_take_boxed (value, tp_value_array_build (3,
149 G_TYPE_INT, 0,
150 G_TYPE_UINT, G_MAXUINT32,
151 G_TYPE_STRING, "",
152 G_TYPE_INVALID));
153 break;
154
155 default:
156 G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec);
157 break;
158 }
159 }
160
161 static void
unbalanced_connection_init(UnbalancedConnection * self G_GNUC_UNUSED)162 unbalanced_connection_init (UnbalancedConnection *self G_GNUC_UNUSED)
163 {
164 }
165
166 static void
unbalanced_connection_class_init(UnbalancedConnectionClass * cls)167 unbalanced_connection_class_init (UnbalancedConnectionClass *cls)
168 {
169 GObjectClass *object_class = (GObjectClass *) cls;
170
171 object_class->get_property = unbalanced_connection_get_property;
172
173 g_object_class_override_property (object_class, PROP_ACCOUNT_BALANCE,
174 "account-balance");
175 }
176
177 /* -- Tests -- */
178 typedef struct {
179 GMainLoop *mainloop;
180 TpDBusDaemon *dbus;
181 DBusConnection *client_libdbus;
182 DBusGConnection *client_dbusglib;
183 TpDBusDaemon *client_bus;
184 TpTestsSimpleConnection *service_conn;
185 TpBaseConnection *service_conn_as_base;
186 gchar *conn_name;
187 gchar *conn_path;
188 TpConnection *conn;
189
190 gboolean cwr_ready;
191 GError *cwr_error /* initialized in setup */;
192
193 GError *error /* initialized where needed */;
194 gint wait;
195 } Test;
196
197 static void
setup(Test * test,gconstpointer data)198 setup (Test *test,
199 gconstpointer data)
200 {
201 GError *error = NULL;
202 GQuark features[] = { TP_CONNECTION_FEATURE_CONNECTED, 0 };
203 GType conn_type = GPOINTER_TO_SIZE (data);
204
205 tp_debug_set_flags ("all");
206 test->dbus = tp_tests_dbus_daemon_dup_or_die ();
207
208 test->mainloop = g_main_loop_new (NULL, FALSE);
209 test->error = NULL;
210
211 test->client_libdbus = dbus_bus_get_private (DBUS_BUS_STARTER, NULL);
212 g_assert (test->client_libdbus != NULL);
213 dbus_connection_setup_with_g_main (test->client_libdbus, NULL);
214 dbus_connection_set_exit_on_disconnect (test->client_libdbus, FALSE);
215 test->client_dbusglib = dbus_connection_get_g_connection (
216 test->client_libdbus);
217 dbus_g_connection_ref (test->client_dbusglib);
218 test->client_bus = tp_dbus_daemon_new (test->client_dbusglib);
219 g_assert (test->client_bus != NULL);
220
221 test->service_conn = tp_tests_object_new_static_class (
222 conn_type,
223 "account", "me@example.com",
224 "protocol", "simple-protocol",
225 NULL);
226 test->service_conn_as_base = TP_BASE_CONNECTION (test->service_conn);
227 g_assert (test->service_conn != NULL);
228 g_assert (test->service_conn_as_base != NULL);
229
230 g_assert (tp_base_connection_register (test->service_conn_as_base, "simple",
231 &test->conn_name, &test->conn_path, &error));
232 g_assert_no_error (error);
233
234 test->cwr_ready = FALSE;
235 test->cwr_error = NULL;
236
237 test->conn = tp_connection_new (test->client_bus, test->conn_name,
238 test->conn_path, &error);
239 g_assert (test->conn != NULL);
240 g_assert_no_error (error);
241
242 tp_cli_connection_call_connect (test->conn, -1, NULL, NULL, NULL, NULL);
243
244 g_assert (!tp_proxy_is_prepared (test->conn, TP_CONNECTION_FEATURE_CORE));
245 g_assert (!tp_proxy_is_prepared (test->conn,
246 TP_CONNECTION_FEATURE_CONNECTED));
247 g_assert (!tp_proxy_is_prepared (test->conn, TP_CONNECTION_FEATURE_BALANCE));
248
249 tp_tests_proxy_run_until_prepared (test->conn, features);
250 }
251
252 static void
teardown(Test * test,gconstpointer data G_GNUC_UNUSED)253 teardown (Test *test,
254 gconstpointer data G_GNUC_UNUSED)
255 {
256 TpConnection *conn;
257 GError *error = NULL;
258
259 g_clear_error (&test->error);
260 tp_clear_pointer (&test->mainloop, g_main_loop_unref);
261 tp_clear_object (&test->conn);
262
263 /* disconnect the connection so we don't leak it */
264 conn = tp_connection_new (test->dbus, test->conn_name, test->conn_path,
265 &error);
266 g_assert (conn != NULL);
267 g_assert_no_error (error);
268
269 tp_tests_connection_assert_disconnect_succeeds (conn);
270
271 g_assert (!tp_connection_run_until_ready (conn, FALSE, &error, NULL));
272 g_assert_error (error, TP_ERROR, TP_ERROR_CANCELLED);
273 g_clear_error (&error);
274
275 test->service_conn_as_base = NULL;
276 g_object_unref (test->service_conn);
277 g_free (test->conn_name);
278 g_free (test->conn_path);
279
280 g_object_unref (test->dbus);
281 test->dbus = NULL;
282 g_object_unref (test->client_bus);
283 test->client_bus = NULL;
284
285 dbus_g_connection_unref (test->client_dbusglib);
286 dbus_connection_close (test->client_libdbus);
287 dbus_connection_unref (test->client_libdbus);
288 }
289
290 static void
balance_changed_cb(TpConnection * conn,gint balance,guint scale,const gchar * currency,Test * test)291 balance_changed_cb (TpConnection *conn,
292 gint balance,
293 guint scale,
294 const gchar *currency,
295 Test *test)
296 {
297 g_assert_cmpint (balance, ==, BALANCE * 2);
298 g_assert_cmpuint (scale, ==, BALANCE_SCALE);
299 g_assert_cmpstr (currency, ==, BALANCE_CURRENCY);
300
301 test->wait--;
302 if (test->wait <= 0)
303 g_main_loop_quit (test->mainloop);
304 }
305
306 static void
test_balance(Test * test,gconstpointer nil G_GNUC_UNUSED)307 test_balance (Test *test,
308 gconstpointer nil G_GNUC_UNUSED)
309 {
310 GQuark features[] = { TP_CONNECTION_FEATURE_BALANCE, 0 };
311 gint balance;
312 guint scale;
313 const gchar *currency, *uri;
314 gchar *currency_alloc, *uri_alloc;
315 GValueArray *v;
316
317 g_assert (!tp_proxy_is_prepared (test->conn, TP_CONNECTION_FEATURE_BALANCE));
318
319 tp_tests_proxy_run_until_prepared (test->conn, features);
320
321 g_assert (tp_connection_get_balance (test->conn,
322 &balance, &scale, ¤cy));
323
324 g_assert_cmpint (balance, ==, BALANCE);
325 g_assert_cmpuint (scale, ==, BALANCE_SCALE);
326 g_assert_cmpstr (currency, ==, BALANCE_CURRENCY);
327
328 uri = tp_connection_get_balance_uri (test->conn);
329
330 g_assert_cmpstr (uri, ==, MANAGE_CREDIT_URI);
331
332 g_object_get (test->conn,
333 "balance", &balance,
334 "balance-scale", &scale,
335 "balance-currency", ¤cy_alloc,
336 "balance-uri", &uri_alloc,
337 NULL);
338
339 g_assert_cmpint (balance, ==, BALANCE);
340 g_assert_cmpuint (scale, ==, BALANCE_SCALE);
341 g_assert_cmpstr (currency_alloc, ==, BALANCE_CURRENCY);
342 g_assert_cmpstr (uri_alloc, ==, MANAGE_CREDIT_URI);
343
344 v = tp_value_array_build (3,
345 G_TYPE_INT, BALANCE * 2,
346 G_TYPE_UINT, BALANCE_SCALE,
347 G_TYPE_STRING, BALANCE_CURRENCY,
348 G_TYPE_INVALID);
349
350 tp_svc_connection_interface_balance_emit_balance_changed (
351 test->service_conn_as_base, v);
352
353 g_signal_connect (test->conn, "balance-changed",
354 G_CALLBACK (balance_changed_cb), test);
355
356 test->wait = 1;
357 g_main_loop_run (test->mainloop);
358 g_assert_no_error (test->error);
359
360 g_free (currency_alloc);
361 g_free (uri_alloc);
362 }
363
364 static void
test_balance_unknown(Test * test,gconstpointer nil G_GNUC_UNUSED)365 test_balance_unknown (Test *test,
366 gconstpointer nil G_GNUC_UNUSED)
367 {
368 GQuark features[] = { TP_CONNECTION_FEATURE_BALANCE, 0 };
369 gint balance;
370 guint scale;
371 const gchar *currency;
372
373 g_assert (!tp_proxy_is_prepared (test->conn, TP_CONNECTION_FEATURE_BALANCE));
374
375 tp_tests_proxy_run_until_prepared (test->conn, features);
376
377 g_assert (!tp_connection_get_balance (test->conn,
378 &balance, &scale, ¤cy));
379 }
380
381 int
main(int argc,char ** argv)382 main (int argc,
383 char **argv)
384 {
385 tp_tests_abort_after (5);
386 g_test_init (&argc, &argv, NULL);
387
388 g_test_add ("/conn/balance", Test,
389 GSIZE_TO_POINTER (TYPE_BALANCED_CONNECTION),
390 setup, test_balance, teardown);
391 g_test_add ("/conn/balance-unknown", Test,
392 GSIZE_TO_POINTER (TYPE_UNBALANCED_CONNECTION),
393 setup, test_balance_unknown, teardown);
394 g_test_add ("/conn/balance-unimplemented", Test,
395 GSIZE_TO_POINTER (TP_TESTS_TYPE_SIMPLE_CONNECTION),
396 setup, test_balance_unknown, teardown);
397
398 return tp_tests_run_with_bus ();
399 }
400