Unit tests of new API
[accounts-sso:signon-glib.git] / tests / check_signon.c
1 /**
2  * Copyright (C) 2009 Nokia Corporation.
3  * Contact: Alberto Mardegan <alberto.mardegan@nokia.com>
4  * Licensed under the terms of Nokia EUSA (see the LICENSE file)
5  */
6
7 /**
8  * @example check_signon.c
9  * Shows how to initialize the framework.
10  */
11 #include "libsignon-glib/signon-internals.h"
12 #include "libsignon-glib/signon-auth-service.h"
13 #include "libsignon-glib/signon-auth-session.h"
14 #include "libsignon-glib/signon-identity.h"
15 #include "libsignon-glib/signon-client-glib-gen.h"
16 #include "libsignon-glib/signon-identity-glib-gen.h"
17 #include "libsignon-glib/signon-errors.h"
18
19 #include <glib.h>
20 #include <check.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <dbus/dbus-glib.h>
24
25 static GMainLoop *main_loop = NULL;
26 static SignonIdentity *identity = NULL;
27 static SignonAuthService *auth_service = NULL;
28
29 static void
30 end_test ()
31 {
32     if (auth_service)
33     {
34         g_object_unref (auth_service);
35         auth_service = NULL;
36     }
37
38     if (identity)
39     {
40         g_object_unref (identity);
41         identity = NULL;
42     }
43
44     if (main_loop)
45     {
46         g_main_loop_quit (main_loop);
47         g_main_loop_unref (main_loop);
48         main_loop = NULL;
49     }
50 }
51
52 START_TEST(test_init)
53 {
54     g_type_init ();
55
56     auth_service = signon_auth_service_new ();
57     main_loop = g_main_loop_new (NULL, FALSE);
58
59     fail_unless (SIGNON_IS_AUTH_SERVICE (auth_service),
60                  "Failed to initialize the AuthService.");
61     end_test ();
62 }
63 END_TEST
64
65 static void
66 signon_query_methods_cb (SignonAuthService *auth_service, gchar **methods,
67                          GError *error, gpointer user_data)
68 {
69     if (error)
70     {
71         g_warning ("%s: %s", G_STRFUNC, error->message);
72         g_main_loop_quit (main_loop);
73         fail();
74     }
75
76     gboolean has_sasl = FALSE;
77
78     fail_unless (g_strcmp0 (user_data, "Hello") == 0, "Got wrong string");
79     fail_unless (methods != NULL, "The methods does not exist");
80
81     while (*methods)
82     {
83         if (g_strcmp0 (*methods, "sasl") == 0)
84         {
85             has_sasl = TRUE;
86             break;
87         }
88         methods++;
89     }
90     fail_unless (has_sasl, "sasl method does not exist");
91
92     g_main_loop_quit (main_loop);
93 }
94
95 START_TEST(test_query_methods)
96 {
97     g_type_init ();
98
99     if(!main_loop)
100         main_loop = g_main_loop_new (NULL, FALSE);
101
102     auth_service = signon_auth_service_new ();
103
104     fail_unless (SIGNON_IS_AUTH_SERVICE (auth_service),
105                  "Failed to initialize the AuthService.");
106
107     signon_auth_service_query_methods (auth_service, (SignonQueryMethodsCb)signon_query_methods_cb, "Hello");
108     g_main_loop_run (main_loop);
109     end_test ();
110 }
111 END_TEST
112
113 static void
114 signon_query_mechanisms_cb (SignonAuthService *auth_service, gchar *method,
115         gchar **mechanisms, GError *error, gpointer user_data)
116 {
117     if (error)
118     {
119         g_warning ("%s: %s", G_STRFUNC, error->message);
120         g_main_loop_quit (main_loop);
121         fail();
122     }
123
124     gboolean has_plain = FALSE;
125     gboolean has_digest = FALSE;
126
127     fail_unless (strcmp (user_data, "Hello") == 0, "Got wrong string");
128     fail_unless (mechanisms != NULL, "The mechanisms does not exist");
129
130     while (*mechanisms)
131     {
132         if (g_strcmp0 (*mechanisms, "PLAIN") == 0)
133             has_plain = TRUE;
134
135         if (g_strcmp0 (*mechanisms, "DIGEST-MD5") == 0)
136             has_digest = TRUE;
137
138         mechanisms++;
139     }
140
141     fail_unless (has_plain, "PLAIN mechanism does not exist");
142     fail_unless (has_digest, "DIGEST-MD5 mechanism does not exist");
143
144     g_main_loop_quit (main_loop);
145 }
146
147 START_TEST(test_query_mechanisms)
148 {
149     g_type_init ();
150
151     auth_service = signon_auth_service_new ();
152
153     fail_unless (SIGNON_IS_AUTH_SERVICE (auth_service),
154                  "Failed to initialize the AuthService.");
155
156     signon_auth_service_query_mechanisms (auth_service,
157                                           "sasl",
158                                           (SignonQueryMechanismCb)signon_query_mechanisms_cb,
159                                           "Hello");
160     if(!main_loop)
161         main_loop = g_main_loop_new (NULL, FALSE);
162
163     g_main_loop_run (main_loop);
164     end_test ();
165 }
166 END_TEST
167
168
169 static gboolean
170 test_quit_main_loop_cb (gpointer data)
171 {
172     g_main_loop_quit (main_loop);
173     return FALSE;
174 }
175
176 static void
177 test_auth_session_query_mechanisms_cb (SignonAuthSession *self,
178                                       gchar **mechanisms,
179                                       const GError *error,
180                                       gpointer user_data)
181 {
182     if (error)
183     {
184         g_warning ("%s: %s", G_STRFUNC, error->message);
185         g_main_loop_quit (main_loop);
186         fail();
187     }
188
189     fail_unless (mechanisms != NULL, "The mechanisms does not exist");
190
191     gchar** patterns = (gchar**)user_data;
192
193     int i = g_strv_length(mechanisms);
194     fail_unless( i == g_strv_length(patterns), "The number of obtained methods is wrong: %d %s", i);
195
196     while ( i > 0 )
197     {
198         gchar* pattern = patterns[--i];
199         fail_unless(g_strcmp0(pattern, mechanisms[i]) == 0, "The obtained mechanism differs from predefined pattern: %s vs %s", mechanisms[i], pattern);
200     }
201
202     g_strfreev(mechanisms);
203     g_main_loop_quit (main_loop);
204 }
205
206 START_TEST(test_auth_session_query_mechanisms)
207 {
208     g_type_init();
209
210     GError *err = NULL;
211
212     SignonIdentity *idty = signon_identity_new(NULL, NULL);
213     fail_unless (idty != NULL, "Cannot create Iddentity object");
214
215     SignonAuthSession *auth_session = signon_identity_create_session(idty,
216                                                                      "ssotest",
217                                                                      NULL,
218                                                                      NULL,
219                                                                      &err);
220     fail_unless (auth_session != NULL, "Cannot create AuthSession object");
221
222     g_clear_error(&err);
223
224     gchar* patterns[4];
225     patterns[0] = g_strdup("mech1");
226     patterns[1] = g_strdup("mech2");
227     patterns[2] = g_strdup("mech3");
228     patterns[3] = NULL;
229
230     signon_auth_session_query_available_mechanisms(auth_session,
231                                                   (const gchar**)patterns,
232                                                   test_auth_session_query_mechanisms_cb,
233                                                   (gpointer)patterns);
234     if(!main_loop)
235         main_loop = g_main_loop_new (NULL, FALSE);
236
237     g_main_loop_run (main_loop);
238
239     g_free(patterns[2]);
240     patterns[2] = NULL;
241
242     signon_auth_session_query_available_mechanisms(auth_session,
243                                                   (const gchar**)patterns,
244                                                   test_auth_session_query_mechanisms_cb,
245                                                   (gpointer)patterns);
246
247     g_main_loop_run (main_loop);
248
249     g_free(patterns[1]);
250     patterns[1] = NULL;
251
252     signon_auth_session_query_available_mechanisms(auth_session,
253                                                   (const gchar**)patterns,
254                                                   test_auth_session_query_mechanisms_cb,
255                                                   (gpointer)patterns);
256
257     g_main_loop_run (main_loop);
258
259     g_free(patterns[0]);
260     g_object_unref(idty);
261
262     end_test ();
263 }
264 END_TEST
265
266 static void
267 test_auth_session_query_mechanisms_nonexisting_cb (SignonAuthSession *self,
268                                                   gchar **mechanisms,
269                                                   const GError *error,
270                                                   gpointer user_data)
271 {
272     if (!error)
273     {
274         g_main_loop_quit (main_loop);
275         fail();
276         return;
277     }
278
279     g_warning ("%s: %s", G_STRFUNC, error->message);
280     g_main_loop_quit (main_loop);
281 }
282
283 START_TEST(test_auth_session_query_mechanisms_nonexisting)
284 {
285     g_type_init();
286     GError *err = NULL;
287
288     SignonIdentity *idty = signon_identity_new(NULL, NULL);
289     fail_unless (idty != NULL, "Cannot create Iddentity object");
290
291     SignonAuthSession *auth_session = signon_identity_create_session(idty,
292                                                                      "nonexisting",
293                                                                      NULL,
294                                                                      NULL,
295                                                                      &err);
296
297     fail_unless (auth_session != NULL, "Cannot create AuthSession object");
298
299     g_clear_error(&err);
300
301     gchar* patterns[4];
302     patterns[0] = g_strdup("mech1");
303     patterns[1] = g_strdup("mech2");
304     patterns[2] = g_strdup("mech3");
305     patterns[3] = NULL;
306
307     signon_auth_session_query_available_mechanisms(auth_session,
308                                                   (const gchar**)patterns,
309                                                   test_auth_session_query_mechanisms_nonexisting_cb,
310                                                   (gpointer)patterns);
311     if(!main_loop)
312         main_loop = g_main_loop_new (NULL, FALSE);
313
314     g_main_loop_run (main_loop);
315
316     g_free(patterns[0]);
317     g_object_unref(idty);
318
319     end_test ();
320 }
321 END_TEST
322
323 static void
324 test_auth_session_states_cb (SignonAuthSession *self,
325                              gint state,
326                              gchar *message,
327                              gpointer user_data)
328 {
329     gint *state_counter = (gint *)user_data;
330     (*state_counter)++;
331 }
332
333 static void
334 test_auth_session_process_cb (SignonAuthSession *self,
335                              GHashTable *sessionData,
336                              const GError *error,
337                              gpointer user_data)
338 {
339     if (error)
340     {
341         g_warning ("%s: %s", G_STRFUNC, error->message);
342         g_main_loop_quit (main_loop);
343         fail();
344     }
345
346     fail_unless (sessionData != NULL, "The result is empty");
347
348     gchar* usernameKey = g_strdup(SIGNON_SESSION_DATA_USERNAME);
349     GValue* usernameVa = (GValue*)g_hash_table_lookup(sessionData, usernameKey);
350
351     gchar* realmKey = g_strdup(SIGNON_SESSION_DATA_REALM);
352     GValue* realmVa = (GValue*)g_hash_table_lookup(sessionData, realmKey);
353
354     fail_unless(g_strcmp0(g_value_get_string(usernameVa), "test_username") == 0, "Wrong value of username");
355     fail_unless(g_strcmp0(g_value_get_string(realmVa), "testRealm_after_test") == 0, "Wrong value of realm");
356
357     g_hash_table_destroy(sessionData);
358
359     g_free(usernameKey);
360     g_free(realmKey);
361
362     g_main_loop_quit (main_loop);
363 }
364
365 START_TEST(test_auth_session_creation)
366 {
367     g_type_init();
368     gint state_counter = 0;
369     GError *err = NULL;
370
371     SignonIdentity *idty = signon_identity_new(NULL, NULL);
372     fail_unless (idty != NULL, "Cannot create Iddentity object");
373
374     SignonAuthSession *auth_session = signon_identity_create_session(idty,
375                                                                     "ssotest",
376                                                                     test_auth_session_states_cb,
377                                                                     &state_counter,
378                                                                     &err);
379
380     fail_unless (auth_session != NULL, "Cannot create AuthSession object");
381
382     g_object_unref (idty);
383     fail_unless (SIGNON_IS_IDENTITY(idty), "Identity must stay untill all its session are not destroyed");
384     g_object_unref (auth_session);
385
386     fail_if (SIGNON_IS_AUTH_SESSION(auth_session), "AuthSession is not synchronized with parent Identity");
387     fail_if (SIGNON_IS_IDENTITY(idty), "Identity is not synchronized with its AuthSession");
388
389     g_clear_error(&err);
390 }
391 END_TEST
392
393 START_TEST(test_auth_session_process)
394 {
395     g_type_init();
396     gint state_counter = 0;
397     GError *err = NULL;
398
399     SignonIdentity *idty = signon_identity_new(NULL, NULL);
400     fail_unless (idty != NULL, "Cannot create Iddentity object");
401
402     SignonAuthSession *auth_session = signon_identity_create_session(idty,
403                                                                      "ssotest",
404                                                                      test_auth_session_states_cb,
405                                                                      &state_counter,
406                                                                      &err);
407
408     fail_unless (auth_session != NULL, "Cannot create AuthSession object");
409
410     g_clear_error(&err);
411
412     GHashTable* sessionData = g_hash_table_new(g_str_hash,
413                                                g_str_equal);
414     GValue* usernameVa = g_new0(GValue, 1);
415     gchar* usernameKey = g_strdup(SIGNON_SESSION_DATA_USERNAME);
416     g_value_init (usernameVa, G_TYPE_STRING);
417     g_value_set_static_string(usernameVa, "test_username");
418
419     g_hash_table_insert (sessionData,
420                          usernameKey,
421                          usernameVa);
422
423     GValue* passwordVa = g_new0(GValue, 1);
424     gchar* passwordKey = g_strdup(SIGNON_SESSION_DATA_SECRET);
425
426     g_value_init (passwordVa, G_TYPE_STRING);
427     g_value_set_static_string(passwordVa, "test_username");
428
429     g_hash_table_insert (sessionData,
430                          passwordKey,
431                          passwordVa);
432
433     signon_auth_session_process(auth_session,
434                                sessionData,
435                                "mech1",
436                                test_auth_session_process_cb,
437                                sessionData);
438     if(!main_loop)
439         main_loop = g_main_loop_new (NULL, FALSE);
440
441
442     g_main_loop_run (main_loop);
443     fail_unless (state_counter == 12, "Wrong numer of state change signals: %d", state_counter);
444     state_counter = 0;
445
446     signon_auth_session_process(auth_session,
447                                sessionData,
448                                "mech1",
449                                test_auth_session_process_cb,
450                                sessionData);
451
452     g_main_loop_run (main_loop);
453     fail_unless (state_counter == 12, "Wrong numer of state change signals: %d", state_counter);
454     state_counter = 0;
455
456     signon_auth_session_process(auth_session,
457                                sessionData,
458                                "mech1",
459                                test_auth_session_process_cb,
460                                sessionData);
461
462     g_main_loop_run (main_loop);
463     fail_unless (state_counter == 12, "Wrong numer of state change signals: %d", state_counter);
464     state_counter = 0;
465
466     g_object_unref (auth_session);
467     g_object_unref (idty);
468
469     g_value_unset(usernameVa);
470     g_free(usernameVa);
471     g_free(usernameKey);
472
473     g_value_unset(passwordVa);
474     g_free(passwordVa);
475     g_free(passwordKey);
476
477
478 }
479 END_TEST
480
481 static GHashTable *create_methods_hashtable()
482 {
483     gchar *mechanisms[] = {
484             "mechanism1",
485             "mechanism2",
486             "mechanism3",
487             NULL
488     };
489
490     GHashTable *methods = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
491                                                 (GDestroyNotify)g_strfreev);
492
493     g_hash_table_insert (methods, g_strdup("method1"), g_strdupv(mechanisms));
494     g_hash_table_insert (methods, g_strdup("method2"), g_strdupv(mechanisms));
495     g_hash_table_insert (methods, g_strdup("method3"), g_strdupv(mechanisms));
496
497     return methods;
498 }
499
500 static guint
501 new_identity()
502 {
503     DBusGConnection *connection;
504     DBusGProxy *proxy;
505     guint id = 0;
506     GError *error = NULL;
507
508     connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
509
510     if(connection)
511     {
512         proxy = dbus_g_proxy_new_for_name (connection,
513                                            "com.nokia.singlesignon",
514                                            "/SignonDaemon",
515                                            "com.nokia.singlesignon.SignonDaemon");
516     }
517     else if (error)
518     {
519         g_warning ("%s %d returned error: %s", G_STRFUNC, __LINE__, error->message);
520         g_error_free (error);
521     }
522
523     gchar *objectPath;
524     com_nokia_singlesignon_SignonDaemon_register_new_identity (proxy, &objectPath, &error);
525
526     if (error)
527     {
528         g_warning ("%s %d returned error: %s", G_STRFUNC, __LINE__, error->message);
529         g_error_free (error);
530         fail();
531     }
532
533     GHashTable *methods = g_hash_table_new (g_str_hash, g_str_equal);
534
535     proxy = dbus_g_proxy_new_for_name (connection,
536                                        "com.nokia.singlesignon",
537                                        objectPath,
538                                        "com.nokia.singlesignon.SignonIdentity");
539
540     com_nokia_singlesignon_SignonIdentity_store_credentials (proxy,
541                                                              0,
542                                                              "James Bond",
543                                                              "007",
544                                                              1,
545                                                              methods,
546                                                              "caption",
547                                                              NULL,
548                                                              NULL,
549                                                              0,
550                                                              &id,
551                                                              &error);
552
553     g_hash_table_destroy (methods);
554
555     if(error)
556     {
557         g_warning ("%s %d: %s", G_STRFUNC, __LINE__, error->message);
558         fail();
559     }
560
561     return id;
562
563 }
564
565 static gboolean
566 identity_registered_cb (gpointer data)
567 {
568     g_main_loop_quit (main_loop);
569     return FALSE;
570 }
571
572 START_TEST(test_get_existing_identity)
573 {
574     g_type_init ();
575
576     guint id = new_identity();
577
578     fail_unless (id != 0);
579
580     identity = signon_identity_new_from_db(id, NULL, NULL);
581
582     fail_unless (identity != NULL);
583     fail_unless (SIGNON_IS_IDENTITY (identity),
584                  "Failed to initialize the Identity.");
585
586     g_timeout_add (1000, identity_registered_cb, identity);
587     main_loop = g_main_loop_new (NULL, FALSE);
588     g_main_loop_run (main_loop);
589
590     end_test ();
591 }
592 END_TEST
593
594 START_TEST(test_get_nonexisting_identity)
595 {
596     g_type_init ();
597
598     identity = signon_identity_new_from_db(G_MAXINT, NULL, NULL);
599
600     fail_unless (identity != NULL);
601     fail_unless (SIGNON_IS_IDENTITY (identity),
602                  "Failed to initialize the Identity.");
603
604     g_timeout_add (1000, identity_registered_cb, identity);
605     main_loop = g_main_loop_new (NULL, FALSE);
606     g_main_loop_run (main_loop);
607
608     GError *error = NULL;
609     error = signon_identity_get_last_error(identity);
610     fail_unless (error != NULL);
611
612     GQuark domain = error->domain;
613
614     fail_unless (error->domain == SIGNON_ERROR);
615     fail_unless (error->code == SIGNON_ERROR_NOT_FOUND);
616
617     end_test ();
618 }
619 END_TEST
620
621 static void store_credentials_identity_cb(SignonIdentity *self,
622                                          guint32 id,
623                                          const GError *error,
624                                          gpointer user_data)
625 {
626     if(error)
627     {
628         g_warning ("%s %d: %s", G_STRFUNC, __LINE__, error->message);
629         fail();
630     }
631
632     fail_unless (id > 0);
633
634     if (user_data != NULL)
635     {
636         gint *last_id = (gint *)user_data;
637         g_warning ("%s (prev_id vs new_id): %d vs %d", G_STRFUNC, *last_id, id);
638
639         fail_unless (id == (*last_id) + 1);
640         (*last_id) += 1;
641     }
642
643     g_main_loop_quit (main_loop);
644 }
645
646 START_TEST(test_store_credentials_identity)
647 {
648     g_type_init ();
649     SignonIdentity *idty = signon_identity_new(NULL, NULL);
650     fail_unless (idty != NULL);
651     fail_unless (SIGNON_IS_IDENTITY (idty),
652                  "Failed to initialize the Identity.");
653
654     gint last_id = new_identity();
655
656     GHashTable *methods = create_methods_hashtable();
657
658     signon_identity_store_credentials_with_args (idty,
659                                                  "James Bond",
660                                                  "007",
661                                                  1,
662                                                  methods,
663                                                  "caption",
664                                                  NULL,
665                                                  NULL,
666                                                  0,
667                                                  store_credentials_identity_cb,
668                                                  &last_id);
669     g_hash_table_destroy (methods);
670
671     g_timeout_add (1000, test_quit_main_loop_cb, idty);
672     main_loop = g_main_loop_new (NULL, FALSE);
673     g_main_loop_run (main_loop);
674
675     g_object_unref(idty);
676     end_test ();
677 }
678 END_TEST
679
680 static void identity_verify_secret_cb(SignonIdentity *self,
681                                       gboolean valid,
682                                       const GError *error,
683                                       gpointer user_data)
684 {
685     fail_unless (error == NULL, "The callback returned error for proper secret");
686     fail_unless (valid == TRUE, "The callback gives FALSE for proper secret");
687     g_main_loop_quit((GMainLoop *)user_data);
688 }
689
690 static void identity_verify_username_cb(SignonIdentity *self,
691                                         gboolean valid,
692                                         const GError *error,
693                                         gpointer user_data)
694 {
695     fail_unless (error != NULL, "The callback returned NULL error for unimplemented function");
696     g_warning ("Error: %s ", error->message);
697
698     g_main_loop_quit((GMainLoop *)user_data);
699 }
700
701
702 START_TEST(test_verify_secret_identity)
703 {
704     g_type_init ();
705     SignonIdentity *idty = signon_identity_new(NULL, NULL);
706     fail_unless (idty != NULL);
707     fail_unless (SIGNON_IS_IDENTITY (idty),
708                  "Failed to initialize the Identity.");
709
710     GHashTable *methods = create_methods_hashtable();
711
712     gchar username[] = "James Bond";
713     gchar secret[] = "007";
714     gchar caption[] = "caption";
715
716     signon_identity_store_credentials_with_args (idty,
717                                                  username,
718                                                  secret,
719                                                  1,
720                                                  methods,
721                                                  caption,
722                                                  NULL,
723                                                  NULL,
724                                                  0,
725                                                  store_credentials_identity_cb,
726                                                  NULL);
727     main_loop = g_main_loop_new (NULL, FALSE);
728
729     signon_identity_verify_secret(idty,
730                                  secret,
731                                  identity_verify_secret_cb,
732                                  main_loop);
733
734     g_main_loop_run (main_loop);
735
736     signon_identity_verify_user(idty,
737                                username,
738                                identity_verify_username_cb,
739                                main_loop);
740
741     g_main_loop_run (main_loop);
742
743     g_hash_table_destroy (methods);
744     g_object_unref (idty);
745     end_test ();
746 }
747 END_TEST
748
749 static void identity_remove_cb(SignonIdentity *self, const GError *error, gpointer user_data)
750 {
751
752     g_warning (" %s ", __func__);
753      if (error)
754      {
755         g_warning ("Error: %s ", error->message);
756         fail_if (user_data == NULL, "There should be no error in callback");
757      }
758     else
759     {
760         g_warning ("No error");
761         fail_if (user_data != NULL, "The callback must return an error");
762     }
763
764     g_main_loop_quit(main_loop);
765 }
766
767 START_TEST(test_remove_identity)
768 {
769     g_type_init ();
770     SignonIdentity *idty = signon_identity_new(NULL, NULL);
771     fail_unless (idty != NULL);
772     fail_unless (SIGNON_IS_IDENTITY (idty),
773                  "Failed to initialize the Identity.");
774
775     main_loop = g_main_loop_new (NULL, FALSE);
776     /*
777      * Try to remove non-stored idetnity
778      * */
779     signon_identity_remove(idty, identity_remove_cb, NULL);
780     g_main_loop_run (main_loop);
781
782     GHashTable *methods = create_methods_hashtable();
783
784     gchar username[] = "James Bond";
785     gchar secret[] = "007";
786     gchar caption[] = "caption";
787
788     signon_identity_store_credentials_with_args (idty,
789                                                  username,
790                                                  secret,
791                                                  1,
792                                                  methods,
793                                                  caption,
794                                                  NULL,
795                                                  NULL,
796                                                  0,
797                                                  store_credentials_identity_cb,
798                                                  NULL);
799     g_hash_table_destroy (methods);
800     g_main_loop_run (main_loop);
801
802     signon_identity_remove(idty, identity_remove_cb, NULL);
803     g_main_loop_run (main_loop);
804
805     /*
806      * Try to remove existing identy
807      * */
808
809     gint id = new_identity();
810     SignonIdentity *idty2 = signon_identity_new_from_db (id, NULL, NULL);
811
812     signon_identity_remove(idty2, identity_remove_cb, NULL);
813     g_main_loop_run (main_loop);
814
815     /*
816      * Try to remove already removed
817      * */
818
819     signon_identity_remove(idty2, identity_remove_cb, GINT_TO_POINTER(TRUE));
820
821     g_object_unref (idty);
822     g_object_unref (idty2);
823     end_test ();
824 }
825 END_TEST
826
827 static void identity_info_cb(SignonIdentity *self, const SignonIdentityInfo *info, const GError *error, gpointer user_data)
828 {
829      if (error)
830      {
831         g_warning ("%s: Error: %s ", __func__, error->message);
832         fail_if (info != NULL, "Error: %s ", error->message);
833         g_main_loop_quit(main_loop);
834         return;
835      }
836
837      g_warning ("No error");
838
839      SignonIdentityInfo **pattern_ptr = (SignonIdentityInfo **)user_data;
840      SignonIdentityInfo *pattern = NULL;
841
842      if (pattern_ptr)
843          pattern = (*pattern_ptr);
844
845      if (pattern == NULL)
846          fail_unless (info == NULL, "The info must be NULL");
847      else
848      {
849          fail_unless (info != NULL, "The info must be non-null");
850          fail_unless (g_strcmp0 (signon_identity_info_get_username(info),
851                                  signon_identity_info_get_username(pattern)) == 0, "The info has wrong username");
852          fail_unless (g_strcmp0 (signon_identity_info_get_caption(info),
853                                  signon_identity_info_get_caption(pattern)) == 0, "The info has wrong caption");
854
855          GHashTable *methods = (GHashTable *)signon_identity_info_get_methods (info);
856          gchar **mechs1 = g_hash_table_lookup (methods, "method1");
857          gchar **mechs2 = g_hash_table_lookup (methods, "method2");
858          gchar **mechs3 = g_hash_table_lookup (methods, "method3");
859
860          fail_unless (g_strv_length (mechs1) == 3);
861          fail_unless (g_strv_length (mechs2) == 3);
862          fail_unless (g_strv_length (mechs3) == 3);
863
864          fail_unless (g_strcmp0 ("mechanism1", mechs1[0]) == 0 &&
865                       g_strcmp0 ("mechanism2", mechs1[1]) == 0 &&
866                       g_strcmp0 ("mechanism3", mechs1[2]) == 0);
867
868          fail_unless (g_strcmp0 ("mechanism1", mechs2[0]) == 0 &&
869                       g_strcmp0 ("mechanism2", mechs2[1]) == 0 &&
870                       g_strcmp0 ("mechanism3", mechs2[2]) == 0);
871
872          fail_unless (g_strcmp0 ("mechanism1", mechs3[0]) == 0 &&
873                       g_strcmp0 ("mechanism2", mechs3[1]) == 0 &&
874                       g_strcmp0 ("mechanism3", mechs3[2]) == 0);
875      }
876
877      if (info)
878      {
879          signon_identity_info_free (pattern);
880          *pattern_ptr = signon_identity_info_copy (info);
881      }
882
883      g_main_loop_quit(main_loop);
884 }
885
886 START_TEST(test_info_identity)
887 {
888     g_type_init ();
889     SignonIdentity *idty = signon_identity_new(NULL, NULL);
890     fail_unless (idty != NULL);
891     fail_unless (SIGNON_IS_IDENTITY (idty),
892                  "Failed to initialize the Identity.");
893
894     SignonIdentityInfo *info = NULL;
895
896     main_loop = g_main_loop_new (NULL, FALSE);
897     /*
898      * Try to get_info for non-stored idetnity
899      * */
900     signon_identity_query_info (idty, identity_info_cb, &info);
901     g_main_loop_run (main_loop);
902
903     GHashTable *methods = create_methods_hashtable();
904     gint result_id;
905
906     signon_identity_store_credentials_with_args (idty,
907                                                 "James Bond",
908                                                 "007",
909                                                  1,
910                                                  methods,
911                                                  "caption",
912                                                  NULL,
913                                                  NULL,
914                                                  0,
915                                                  store_credentials_identity_cb,
916                                                  NULL);
917     g_hash_table_destroy (methods);
918     g_main_loop_run (main_loop);
919
920     info = signon_identity_info_new ();
921     signon_identity_info_set_username (info, "James Bond");
922     signon_identity_info_set_secret (info, "007", TRUE);
923     signon_identity_info_set_caption (info, "caption");
924
925     gchar *mechanisms[] = {
926             "mechanism1",
927             "mechanism2",
928             "mechanism3",
929             NULL
930     };
931
932     signon_identity_info_set_method (info, "method1", (const gchar **)mechanisms);
933     signon_identity_info_set_method (info, "method2", (const gchar **)mechanisms);
934     signon_identity_info_set_method (info, "method3", (const gchar **)mechanisms);
935
936     signon_identity_query_info (idty, identity_info_cb, &info);
937     g_main_loop_run (main_loop);
938
939     gint id = signon_identity_info_get_id (info);
940     SignonIdentity *idty2 = signon_identity_new_from_db (id, NULL, NULL);
941
942     signon_identity_query_info (idty2, identity_info_cb, &info);
943     g_main_loop_run (main_loop);
944
945     /*
946      * Try to update one identity and
947      * have a look what will happen
948      * */
949     signon_identity_info_set_username (info, "James Bond_2nd version");
950     signon_identity_info_set_caption (info, "caption_2nd version");
951
952     signon_identity_store_credentials_with_info (idty2,
953                                                  info,
954                                                  store_credentials_identity_cb,
955                                                  NULL);
956     g_main_loop_run (main_loop);
957
958     signon_identity_query_info (idty, identity_info_cb, &info);
959     g_main_loop_run (main_loop);
960     /*
961      * Try to remove existing identity and
962      * have a look what will happen
963      * */
964     signon_identity_remove(idty2, identity_remove_cb, NULL);
965     g_main_loop_run (main_loop);
966
967     /*
968      * no main_loops required as
969      * the callback is executed immediately
970      * */
971     signon_identity_query_info (idty2, identity_info_cb, NULL);
972     signon_identity_query_info (idty, identity_info_cb, NULL);
973
974     signon_identity_info_free (info);
975     g_object_unref (idty);
976     g_object_unref (idty2);
977     end_test ();
978 }
979 END_TEST
980
981 START_TEST(test_signout_identity)
982 {
983 /*
984  * TODO: implement the test
985  * */
986 }
987 END_TEST
988
989 Suite *
990 signon_suite(void)
991 {
992     Suite *s = suite_create ("signon-glib");
993
994     /* Core test case */
995     TCase * tc_core = tcase_create("Core");
996     tcase_set_timeout(tc_core, 10);
997     tcase_add_test (tc_core, test_init);
998     tcase_add_test (tc_core, test_query_methods);
999     tcase_add_test (tc_core, test_query_mechanisms);
1000     tcase_add_test (tc_core, test_get_existing_identity);
1001     tcase_add_test (tc_core, test_get_nonexisting_identity);
1002
1003     tcase_add_test (tc_core, test_auth_session_creation);
1004     tcase_add_test (tc_core, test_auth_session_query_mechanisms);
1005     tcase_add_test (tc_core, test_auth_session_query_mechanisms_nonexisting);
1006     tcase_add_test (tc_core, test_auth_session_process);
1007     tcase_add_test (tc_core, test_store_credentials_identity);
1008     tcase_add_test (tc_core, test_verify_secret_identity);
1009     tcase_add_test (tc_core, test_remove_identity);
1010     tcase_add_test (tc_core, test_info_identity);
1011
1012     tcase_add_test (tc_core, test_signout_identity);
1013     suite_add_tcase (s, tc_core);
1014
1015     return s;
1016 }
1017
1018 int main(void)
1019 {
1020     int number_failed;
1021     Suite * s = signon_suite();
1022     SRunner * sr = srunner_create(s);
1023
1024     srunner_set_xml(sr, "/tmp/result.xml");
1025     srunner_run_all(sr, CK_NORMAL);
1026     number_failed = srunner_ntests_failed(sr);
1027     srunner_free (sr);
1028
1029     return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
1030 }
1031
1032 /* vim: set ai et tw=75 ts=4 sw=4: */
1033