diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index 4953e728543612b07f7b1bac026fbd52d1dd8131..c7f81ce0f27b90cab92e67f77bab4fad60f8b23a 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -1,822 +1,822 @@ -/* - vcard_tester.c - Copyright (C) 2015 Belledonne Communications SARL - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#ifdef VCARD_ENABLED - -#include "linphonecore.h" -#include "private.h" -#include "liblinphone_tester.h" -#include "carddav.h" - -#include - -#define CARDDAV_SERVER "http://dav.linphone.org/card.php/addressbooks/tester/default" - -static void linphone_vcard_import_export_friends_test(void) { - LinphoneCoreManager* manager = linphone_core_manager_new2("empty_rc", FALSE); - LinphoneFriendList *lfl = linphone_core_get_default_friend_list(manager->lc); - const bctbx_list_t *friends = linphone_friend_list_get_friends(lfl); - char *import_filepath = bc_tester_res("vcards/vcards.vcf"); - char *export_filepath = bc_tester_file("export_vcards.vcf"); - int count = 0; - BC_ASSERT_EQUAL(bctbx_list_size(friends), 0, int, "%d"); - - count = linphone_friend_list_import_friends_from_vcard4_file(lfl, import_filepath); - BC_ASSERT_EQUAL(count, 3, int, "%d"); - friends = linphone_friend_list_get_friends(lfl); - BC_ASSERT_EQUAL(bctbx_list_size(friends), 3, int, "%d"); - - linphone_friend_list_export_friends_as_vcard4_file(lfl, export_filepath); - - lfl = linphone_core_create_friend_list(manager->lc); - count = linphone_friend_list_import_friends_from_vcard4_file(lfl, export_filepath); - BC_ASSERT_EQUAL(count, 3, int, "%d"); - friends = linphone_friend_list_get_friends(lfl); - BC_ASSERT_EQUAL(bctbx_list_size(friends), 3, int, "%d"); - linphone_friend_list_unref(lfl); - - remove(export_filepath); - ms_free(import_filepath); - ms_free(export_filepath); - linphone_core_manager_destroy(manager); -} - -static void linphone_vcard_import_a_lot_of_friends_test(void) { - LinphoneCoreManager* manager = linphone_core_manager_new2("empty_rc", FALSE); - LinphoneFriendList *lfl = linphone_core_get_default_friend_list(manager->lc); - char *import_filepath = bc_tester_res("vcards/thousand_vcards.vcf"); - clock_t start, end; - double elapsed = 0; - const bctbx_list_t *friends = NULL; - FILE *infile = NULL; - char *buffer = NULL; - long numbytes = 0; - - start = clock(); - linphone_friend_list_import_friends_from_vcard4_file(lfl, import_filepath); - end = clock(); - - friends = linphone_friend_list_get_friends(lfl); - BC_ASSERT_EQUAL(bctbx_list_size(friends), 482, int, "%i"); // Thousand vcards contains 482 contacts with a SIP URI - - elapsed = (double)(end - start); - ms_error("Imported a thousand of vCards from file (only %u friends with SIP address found) in %f seconds", (unsigned int)bctbx_list_size(friends), elapsed / CLOCKS_PER_SEC); - - lfl = linphone_core_create_friend_list(manager->lc); - infile = fopen(import_filepath, "rb"); - BC_ASSERT_PTR_NOT_NULL(infile); - if (infile) { - fseek(infile, 0L, SEEK_END); - numbytes = ftell(infile); - fseek(infile, 0L, SEEK_SET); - buffer = (char*)ms_malloc((numbytes + 1) * sizeof(char)); - numbytes = fread(buffer, sizeof(char), numbytes, infile); - fclose(infile); - buffer[numbytes] = '\0'; - - start = clock(); - linphone_friend_list_import_friends_from_vcard4_buffer(lfl, buffer); - end = clock(); - ms_free(buffer); - } - - friends = linphone_friend_list_get_friends(lfl); - BC_ASSERT_EQUAL(bctbx_list_size(friends), 482, int, "%i"); // Thousand vcards contains 482 contacts with a SIP URI - - elapsed = (double)(end - start); - ms_error("Imported a thousand of vCards from buffer (only %u friends with SIP address found) in %f seconds", (unsigned int)bctbx_list_size(friends), elapsed / CLOCKS_PER_SEC); - - linphone_friend_list_unref(lfl); - - ms_free(import_filepath); - linphone_core_manager_destroy(manager); -} - -#if __clang__ || ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4) -#pragma GCC diagnostic push -#endif -#ifdef _MSC_VER -#pragma warning(disable : 4996) -#else -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#endif - -static void linphone_vcard_update_existing_friends_test(void) { - LinphoneFriend *lf = linphone_friend_new_with_addr("sip:oldfriend@sip.linphone.org"); - - BC_ASSERT_PTR_NOT_NULL(lf); - if (linphone_core_vcard_supported()) { - BC_ASSERT_PTR_NOT_NULL(linphone_friend_get_vcard(lf)); - } else { - BC_ASSERT_PTR_NULL(linphone_friend_get_vcard(lf)); - } - - linphone_friend_edit(lf); - linphone_friend_set_name(lf, "Old Friend"); - linphone_friend_done(lf); - - BC_ASSERT_PTR_NOT_NULL(linphone_friend_get_vcard(lf)); - BC_ASSERT_STRING_EQUAL(linphone_vcard_get_full_name(linphone_friend_get_vcard(lf)), "Old Friend"); - linphone_friend_unref(lf); - lf = NULL; -} - -#if __clang__ || ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4) -#pragma GCC diagnostic pop -#endif - -static void linphone_vcard_phone_numbers_and_sip_addresses(void) { - LinphoneCoreManager* manager = linphone_core_manager_new2("empty_rc", FALSE); - LinphoneVcard *lvc = linphone_vcard_context_get_vcard_from_buffer(manager->lc->vcard_context, "BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Sylvain Berfini\r\nIMPP:sip:sberfini@sip.linphone.org\r\nIMPP;TYPE=home:sip:sylvain@sip.linphone.org\r\nTEL;TYPE=work:0952636505\r\nEND:VCARD\r\n"); - LinphoneFriend *lf = linphone_friend_new_from_vcard(lvc); - bctbx_list_t *sip_addresses = linphone_friend_get_addresses(lf); - bctbx_list_t *phone_numbers = linphone_friend_get_phone_numbers(lf); - LinphoneAddress *addr = NULL; - - BC_ASSERT_EQUAL(bctbx_list_size(sip_addresses), 2, int, "%i"); - BC_ASSERT_EQUAL(bctbx_list_size(phone_numbers), 1, int, "%i"); - if (sip_addresses) bctbx_list_free_with_data(sip_addresses, (void (*)(void *))linphone_address_unref); - if (phone_numbers) bctbx_list_free(phone_numbers); - linphone_friend_unref(lf); - - lvc = linphone_vcard_context_get_vcard_from_buffer(manager->lc->vcard_context, "BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Sylvain Berfini\r\nTEL;TYPE=work:0952636505\r\nTEL:0476010203\r\nEND:VCARD\r\n"); - lf = linphone_friend_new_from_vcard(lvc); - sip_addresses = linphone_friend_get_addresses(lf); - phone_numbers = linphone_friend_get_phone_numbers(lf); - - BC_ASSERT_EQUAL(bctbx_list_size(sip_addresses), 0, int, "%i"); - BC_ASSERT_EQUAL(bctbx_list_size(phone_numbers), 2, int, "%i"); - if (sip_addresses) bctbx_list_free_with_data(sip_addresses, (void (*)(void *))linphone_address_unref); - if (phone_numbers) bctbx_list_free(phone_numbers); - - addr = linphone_address_new("sip:sylvain@sip.linphone.org"); - linphone_friend_add_address(lf, addr); - linphone_address_unref(addr); - sip_addresses = linphone_friend_get_addresses(lf); - BC_ASSERT_EQUAL(bctbx_list_size(sip_addresses), 1, int, "%i"); - if (sip_addresses) bctbx_list_free_with_data(sip_addresses, (void (*)(void *))linphone_address_unref); - - linphone_friend_remove_phone_number(lf, "0952636505"); - phone_numbers = linphone_friend_get_phone_numbers(lf); - BC_ASSERT_EQUAL(bctbx_list_size(phone_numbers), 1, int, "%i"); - if (phone_numbers) bctbx_list_free(phone_numbers); - - linphone_friend_remove_phone_number(lf, "0476010203"); - phone_numbers = linphone_friend_get_phone_numbers(lf); - BC_ASSERT_EQUAL(bctbx_list_size(phone_numbers), 0, int, "%i"); - if (phone_numbers) bctbx_list_free(phone_numbers); - - addr = linphone_address_new("sip:sylvain@sip.linphone.org"); - linphone_friend_remove_address(lf, addr); - linphone_address_unref(addr); - sip_addresses = linphone_friend_get_addresses(lf); - BC_ASSERT_EQUAL(bctbx_list_size(sip_addresses), 0, int, "%i"); - if (sip_addresses) bctbx_list_free_with_data(sip_addresses, (void (*)(void *))linphone_address_unref); - - linphone_friend_add_phone_number(lf, "+33952636505"); - phone_numbers = linphone_friend_get_phone_numbers(lf); - BC_ASSERT_EQUAL(bctbx_list_size(phone_numbers), 1, int, "%i"); - if (phone_numbers) bctbx_list_free(phone_numbers); - - linphone_friend_unref(lf); - lf = NULL; - lvc = NULL; - linphone_core_manager_destroy(manager); -} - -#ifdef SQLITE_STORAGE_ENABLED -static void friends_if_no_db_set(void) { - LinphoneCoreManager* manager = linphone_core_manager_new2("empty_rc", FALSE); - LinphoneFriend *lf = linphone_core_create_friend(manager->lc); - LinphoneAddress *addr = linphone_address_new("sip:sylvain@sip.linphone.org"); - const bctbx_list_t *friends = NULL; - LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc); - - linphone_friend_set_address(lf, addr); - linphone_friend_set_name(lf, "Sylvain"); - linphone_friend_list_add_friend(lfl, lf); - friends = linphone_friend_list_get_friends(lfl); - BC_ASSERT_EQUAL(bctbx_list_size(friends), 1, int, "%d"); - - linphone_friend_list_remove_friend(lfl, lf); - linphone_friend_unref(lf); - friends = linphone_friend_list_get_friends(lfl); - BC_ASSERT_EQUAL(bctbx_list_size(friends), 0, int, "%d"); - - linphone_friend_list_unref(lfl); - linphone_address_unref(addr); - linphone_core_manager_destroy(manager); -} - -static void friends_migration(void) { - LinphoneCoreManager* manager = linphone_core_manager_new2("friends_rc", FALSE); - LpConfig *lpc = linphone_core_get_config(manager->lc); - LinphoneFriendList *lfl = linphone_core_get_default_friend_list(manager->lc); - const bctbx_list_t *friends = linphone_friend_list_get_friends(lfl); - bctbx_list_t *friends_from_db = NULL; - char *friends_db = bc_tester_file("friends.db"); - BC_ASSERT_EQUAL(bctbx_list_size(friends), 3, int, "%d"); - BC_ASSERT_EQUAL(lp_config_get_int(lpc, "misc", "friends_migration_done", 0), 0, int, "%i"); - - unlink(friends_db); - linphone_core_set_friends_database_path(manager->lc, friends_db); - lfl = linphone_core_get_default_friend_list(manager->lc); - friends = linphone_friend_list_get_friends(lfl); - BC_ASSERT_EQUAL(bctbx_list_size(friends), 3, int, "%d"); - friends_from_db = linphone_core_fetch_friends_from_db(manager->lc, lfl); - BC_ASSERT_EQUAL(bctbx_list_size(friends_from_db), 3, int, "%d"); - BC_ASSERT_EQUAL(lp_config_get_int(lpc, "misc", "friends_migration_done", 0), 1, int, "%i"); - - friends_from_db = bctbx_list_free_with_data(friends_from_db, (void (*)(void *))linphone_friend_unref); - unlink(friends_db); - ms_free(friends_db); - linphone_core_manager_destroy(manager); -} - -typedef struct _LinphoneFriendListStats { - int new_list_count; - int removed_list_count; -} LinphoneFriendListStats; - -static void friend_list_created_cb(LinphoneCore *lc, LinphoneFriendList *list) { - LinphoneFriendListStats *stats = (LinphoneFriendListStats *)linphone_friend_list_get_user_data(list); - if (stats) { - stats->new_list_count++; - } -} - -static void friend_list_removed_cb(LinphoneCore *lc, LinphoneFriendList *list) { - LinphoneFriendListStats *stats = (LinphoneFriendListStats *)linphone_friend_list_get_user_data(list); - if (stats) { - stats->removed_list_count++; - } -} - -static void friends_sqlite_storage(void) { - LinphoneCoreVTable *v_table = linphone_core_v_table_new(); - LinphoneCore* lc = NULL; - LinphoneFriendList *lfl = NULL; - LinphoneFriend *lf = NULL; - LinphoneFriend *lf2 = NULL; - LinphoneVcard *lvc = linphone_vcard_new(); - LinphoneAddress *addr = linphone_address_new("sip:sylvain@sip.linphone.org"); - const bctbx_list_t *friends = NULL; - bctbx_list_t *friends_from_db = NULL; - bctbx_list_t *friends_lists_from_db = NULL; - char *friends_db = bc_tester_file("friends.db"); - LinphoneFriendListStats *stats = (LinphoneFriendListStats *)ms_new0(LinphoneFriendListStats, 1); - LinphoneAddress *laddress = NULL, *laddress2 = NULL; - char *address = NULL, *address2 = NULL; - - v_table->friend_list_created = friend_list_created_cb; - v_table->friend_list_removed = friend_list_removed_cb; - lc = linphone_core_new(v_table, NULL, NULL, NULL); - friends = linphone_friend_list_get_friends(linphone_core_get_default_friend_list(lc)); - lfl = linphone_core_create_friend_list(lc); - linphone_friend_list_set_user_data(lfl, stats); - BC_ASSERT_EQUAL(bctbx_list_size(friends), 0, int, "%d"); - - unlink(friends_db); - linphone_core_set_friends_database_path(lc, friends_db); - friends_from_db = linphone_core_fetch_friends_from_db(lc, linphone_core_get_default_friend_list(lc)); - BC_ASSERT_EQUAL(bctbx_list_size(friends_from_db), 0, int, "%d"); - - linphone_vcard_set_etag(lvc, "\"123-456789\""); - linphone_vcard_set_url(lvc, "http://dav.somewhere.fr/addressbook/me/someone.vcf"); - lf = linphone_friend_new_from_vcard(lvc); - linphone_friend_set_address(lf, addr); - linphone_friend_set_name(lf, "Sylvain"); - - linphone_core_add_friend_list(lc, lfl); - wait_for_until(lc, NULL, &stats->new_list_count, 1, 1000); - BC_ASSERT_EQUAL(stats->new_list_count, 1, int, "%i"); - linphone_friend_list_unref(lfl); - linphone_friend_list_set_display_name(lfl, "Test"); - BC_ASSERT_EQUAL(linphone_friend_list_add_friend(lfl, lf), LinphoneFriendListOK, int, "%i"); - linphone_friend_unref(lf); - BC_ASSERT_EQUAL(lfl->storage_id, 1, unsigned int, "%u"); - BC_ASSERT_EQUAL(lf->storage_id, 1, unsigned int, "%u"); - - friends = linphone_friend_list_get_friends(linphone_core_get_default_friend_list(lc)); - BC_ASSERT_EQUAL(bctbx_list_size(friends), 0, int, "%d"); - - friends_lists_from_db = linphone_core_fetch_friends_lists_from_db(lc); - BC_ASSERT_EQUAL(bctbx_list_size(friends_lists_from_db), 1, int, "%d"); - friends_from_db = ((LinphoneFriendList *)friends_lists_from_db->data)->friends; - BC_ASSERT_EQUAL(bctbx_list_size(friends_from_db), 1, int, "%d"); - lf2 = (LinphoneFriend *)friends_from_db->data; - BC_ASSERT_PTR_NOT_NULL(lf2->lc); - BC_ASSERT_PTR_NOT_NULL(lf2->friend_list); - friends_lists_from_db = bctbx_list_free_with_data(friends_lists_from_db, (void (*)(void *))linphone_friend_list_unref); - - friends_from_db = linphone_core_fetch_friends_from_db(lc, lfl); - BC_ASSERT_EQUAL(bctbx_list_size(friends_from_db), 1, int, "%d"); - if (bctbx_list_size(friends_from_db) < 1) { - goto end; - } - lf2 = (LinphoneFriend *)friends_from_db->data; - BC_ASSERT_STRING_EQUAL(linphone_friend_get_name(lf2), linphone_friend_get_name(lf)); - BC_ASSERT_EQUAL(lf2->storage_id, lf->storage_id, unsigned int, "%u"); - BC_ASSERT_STRING_EQUAL(linphone_vcard_get_etag(linphone_friend_get_vcard(lf2)), linphone_vcard_get_etag(linphone_friend_get_vcard(lf))); - BC_ASSERT_STRING_EQUAL(linphone_vcard_get_url(linphone_friend_get_vcard(lf2)), linphone_vcard_get_url(linphone_friend_get_vcard(lf))); - laddress = linphone_friend_get_address(lf); - address = linphone_address_as_string(laddress); - laddress2 = linphone_friend_get_address(lf2); - address2 = linphone_address_as_string(laddress2); - BC_ASSERT_STRING_EQUAL(address2, address); - linphone_address_unref(laddress); - linphone_address_unref(laddress2); - ms_free(address); - ms_free(address2); - - linphone_friend_edit(lf); - linphone_friend_set_name(lf, "Margaux"); - linphone_friend_done(lf); - friends_from_db = bctbx_list_free_with_data(friends_from_db, (void (*)(void *))linphone_friend_unref); - friends_from_db = linphone_core_fetch_friends_from_db(lc, lfl); - BC_ASSERT_EQUAL(bctbx_list_size(friends_from_db), 1, int, "%d"); - if (bctbx_list_size(friends_from_db) < 1) { - goto end; - } - lf2 = (LinphoneFriend *)friends_from_db->data; - BC_ASSERT_STRING_EQUAL(linphone_friend_get_name(lf2), "Margaux"); - friends_from_db = bctbx_list_free_with_data(friends_from_db, (void (*)(void *))linphone_friend_unref); - - linphone_friend_list_remove_friend(lfl, lf); - friends = linphone_friend_list_get_friends(linphone_core_get_default_friend_list(lc)); - BC_ASSERT_EQUAL(bctbx_list_size(friends), 0, int, "%d"); - friends_from_db = linphone_core_fetch_friends_from_db(lc, lfl); - BC_ASSERT_EQUAL(bctbx_list_size(friends_from_db), 0, int, "%d"); - - linphone_core_remove_friend_list(lc, lfl); - wait_for_until(lc, NULL, &stats->removed_list_count, 1, 1000); - BC_ASSERT_EQUAL(stats->removed_list_count, 1, int, "%i"); - -end: - ms_free(stats); - unlink(friends_db); - ms_free(friends_db); - linphone_address_unref(addr); - linphone_core_destroy(lc); - linphone_core_v_table_destroy(v_table); -} -#endif - -typedef struct _LinphoneCardDAVStats { - int sync_done_count; - int new_contact_count; - int removed_contact_count; - int updated_contact_count; -} LinphoneCardDAVStats; - -static void carddav_sync_done(LinphoneCardDavContext *c, bool_t success, const char *message) { - LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_carddav_get_user_data(c); - BC_ASSERT_TRUE(success); - stats->sync_done_count++; -} - -static void carddav_new_contact(LinphoneCardDavContext *c, LinphoneFriend *lf) { - LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_carddav_get_user_data(c); - BC_ASSERT_PTR_NOT_NULL(lf); - stats->new_contact_count++; -} - -static void carddav_removed_contact(LinphoneCardDavContext *c, LinphoneFriend *lf) { - LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_carddav_get_user_data(c); - BC_ASSERT_PTR_NOT_NULL(lf); - stats->removed_contact_count++; -} - -static void carddav_updated_contact(LinphoneCardDavContext *c, LinphoneFriend *new_lf, LinphoneFriend *old_lf) { - LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_carddav_get_user_data(c); - BC_ASSERT_PTR_NOT_NULL(new_lf); - BC_ASSERT_PTR_NOT_NULL(old_lf); - stats->updated_contact_count++; -} - -static void carddav_sync(void) { - LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE); - LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1); - LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc); - LinphoneCardDavContext *c = NULL; - - linphone_friend_list_set_uri(lfl, CARDDAV_SERVER); - linphone_core_add_friend_list(manager->lc, lfl); - linphone_friend_list_unref(lfl); - c = linphone_carddav_context_new(lfl); - BC_ASSERT_PTR_NOT_NULL(c); - - linphone_carddav_set_user_data(c, stats); - linphone_carddav_set_synchronization_done_callback(c, carddav_sync_done); - linphone_carddav_set_new_contact_callback(c, carddav_new_contact); - linphone_carddav_set_removed_contact_callback(c, carddav_removed_contact); - linphone_carddav_set_updated_contact_callback(c, carddav_updated_contact); - linphone_carddav_synchronize(c); - - wait_for_until(manager->lc, NULL, &stats->new_contact_count, 1, 5000); - BC_ASSERT_EQUAL(stats->new_contact_count, 1, int, "%i"); - wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 5000); - BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i"); - - ms_free(stats); - linphone_carddav_context_destroy(c); - linphone_core_manager_destroy(manager); -} - -static void carddav_sync_2(void) { - LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE); - LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1); - LinphoneFriend *lf = linphone_core_create_friend_with_address(manager->lc, "\"Sylvain\" "); - char *friends_db = bc_tester_file("friends.db"); - LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc); - LinphoneCardDavContext *c = NULL; - - linphone_friend_list_set_uri(lfl, CARDDAV_SERVER); - linphone_core_add_friend_list(manager->lc, lfl); - linphone_friend_list_unref(lfl); - c = linphone_carddav_context_new(lfl); - BC_ASSERT_PTR_NOT_NULL(c); - - unlink(friends_db); - linphone_core_set_friends_database_path(manager->lc, friends_db); - BC_ASSERT_EQUAL(linphone_friend_list_add_local_friend(lfl, lf), LinphoneFriendListOK, int, "%d"); - linphone_friend_unref(lf); - - linphone_carddav_set_user_data(c, stats); - linphone_carddav_set_synchronization_done_callback(c, carddav_sync_done); - linphone_carddav_set_new_contact_callback(c, carddav_new_contact); - linphone_carddav_set_removed_contact_callback(c, carddav_removed_contact); - linphone_carddav_set_updated_contact_callback(c, carddav_updated_contact); - - linphone_carddav_synchronize(c); - - wait_for_until(manager->lc, NULL, &stats->new_contact_count, 1, 5000); - BC_ASSERT_EQUAL(stats->new_contact_count, 1, int, "%i"); - wait_for_until(manager->lc, NULL, &stats->removed_contact_count, 1, 5000); - BC_ASSERT_EQUAL(stats->removed_contact_count, 1, int, "%i"); - wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 5000); - BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i"); - - ms_free(stats); - unlink(friends_db); - ms_free(friends_db); - linphone_carddav_context_destroy(c); - linphone_core_manager_destroy(manager); -} - -static void carddav_sync_3(void) { - LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE); - LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1); - LinphoneVcard *lvc = linphone_vcard_context_get_vcard_from_buffer(manager->lc->vcard_context, "BEGIN:VCARD\r\nVERSION:4.0\r\nUID:1f08dd48-29ac-4097-8e48-8596d7776283\r\nFN:Sylvain Berfini\r\nIMPP;TYPE=work:sip:sylvain@sip.linphone.org\r\nEND:VCARD\r\n"); - LinphoneFriend *lf = linphone_friend_new_from_vcard(lvc); - char *friends_db = bc_tester_file("friends.db"); - LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc); - LinphoneCardDavContext *c = NULL; - - linphone_friend_list_set_uri(lfl, CARDDAV_SERVER); - linphone_core_add_friend_list(manager->lc, lfl); - linphone_friend_list_unref(lfl); - c = linphone_carddav_context_new(lfl); - BC_ASSERT_PTR_NOT_NULL(c); - - unlink(friends_db); - linphone_core_set_friends_database_path(manager->lc, friends_db); - BC_ASSERT_EQUAL(linphone_friend_list_add_local_friend(lfl, lf), LinphoneFriendListOK, int, "%d"); - linphone_friend_unref(lf); - - linphone_carddav_set_user_data(c, stats); - linphone_carddav_set_synchronization_done_callback(c, carddav_sync_done); - linphone_carddav_set_new_contact_callback(c, carddav_new_contact); - linphone_carddav_set_removed_contact_callback(c, carddav_removed_contact); - linphone_carddav_set_updated_contact_callback(c, carddav_updated_contact); - - linphone_carddav_synchronize(c); - - wait_for_until(manager->lc, NULL, &stats->updated_contact_count, 1, 5000); - BC_ASSERT_EQUAL(stats->updated_contact_count, 1, int, "%i"); - wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 5000); - BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i"); - - ms_free(stats); - unlink(friends_db); - ms_free(friends_db); - linphone_carddav_context_destroy(c); - c = NULL; - linphone_core_manager_destroy(manager); -} - -static void carddav_sync_4(void) { - LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE); - LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1); - LinphoneVcard *lvc = linphone_vcard_context_get_vcard_from_buffer(manager->lc->vcard_context, "BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Margaux Clerc\r\nIMPP;TYPE=work:sip:margaux@sip.linphone.org\r\nEND:VCARD\r\n"); - LinphoneFriend *lf = linphone_friend_new_from_vcard(lvc); - LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc); - LinphoneCardDavContext *c = NULL; - - linphone_friend_list_set_uri(lfl, CARDDAV_SERVER); - linphone_core_add_friend_list(manager->lc, lfl); - linphone_friend_list_unref(lfl); - c = linphone_carddav_context_new(lfl); - BC_ASSERT_PTR_NOT_NULL(c); - - linphone_carddav_set_user_data(c, stats); - linphone_carddav_set_synchronization_done_callback(c, carddav_sync_done); - linphone_carddav_set_new_contact_callback(c, carddav_new_contact); - linphone_carddav_set_removed_contact_callback(c, carddav_removed_contact); - linphone_carddav_set_updated_contact_callback(c, carddav_updated_contact); - - BC_ASSERT_PTR_NULL(linphone_vcard_get_uid(lvc)); - linphone_carddav_put_vcard(c, lf); - BC_ASSERT_PTR_NOT_NULL(linphone_vcard_get_uid(lvc)); - wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 5000); - BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i"); - - linphone_carddav_delete_vcard(c, lf); - wait_for_until(manager->lc, NULL, &stats->sync_done_count, 2, 5000); - BC_ASSERT_EQUAL(stats->sync_done_count, 2, int, "%i"); - - linphone_friend_unref(lf); - ms_free(stats); - linphone_carddav_context_destroy(c); - linphone_core_manager_destroy(manager); -} - -static void carddav_contact_created(LinphoneFriendList *list, LinphoneFriend *lf) { - LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_friend_list_cbs_get_user_data(list->cbs); - stats->new_contact_count++; -} - -static void carddav_contact_deleted(LinphoneFriendList *list, LinphoneFriend *lf) { - LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_friend_list_cbs_get_user_data(list->cbs); - stats->removed_contact_count++; -} - -static void carddav_contact_updated(LinphoneFriendList *list, LinphoneFriend *new_friend, LinphoneFriend *old_friend) { - LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_friend_list_cbs_get_user_data(list->cbs); - BC_ASSERT_STRING_EQUAL(linphone_vcard_get_full_name(linphone_friend_get_vcard(new_friend)), linphone_vcard_get_full_name(linphone_friend_get_vcard(old_friend))); - stats->updated_contact_count++; -} - -static void carddav_sync_status_changed(LinphoneFriendList *list, LinphoneFriendListSyncStatus status, const char *msg) { - LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_friend_list_cbs_get_user_data(list->cbs); - char *state = status == LinphoneFriendListSyncStarted ? "Sync started" : (status == LinphoneFriendListSyncFailure ? "Sync failure" : "Sync successful"); - ms_message("[CardDAV] %s : %s", state, msg); - if (status == LinphoneFriendListSyncFailure || status == LinphoneFriendListSyncSuccessful) { - stats->sync_done_count++; - } -} - -static void carddav_integration(void) { - LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE); - LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc); - LinphoneVcard *lvc = linphone_vcard_context_get_vcard_from_buffer(manager->lc->vcard_context, "BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Margaux Clerc\r\nIMPP;TYPE=work:sip:margaux@sip.linphone.org\r\nEND:VCARD\r\n"); - LinphoneFriend *lf = linphone_friend_new_from_vcard(lvc); - LinphoneVcard *lvc2 = NULL; - LinphoneFriend *lf2 = NULL; - LinphoneFriendListCbs *cbs = NULL; - LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1); - const char *refkey = "toto"; - char *address = NULL; - LinphoneAddress *addr; - - linphone_friend_list_set_uri(lfl, CARDDAV_SERVER); - cbs = linphone_friend_list_get_callbacks(lfl); - linphone_friend_list_cbs_set_user_data(cbs, stats); - linphone_friend_list_cbs_set_contact_created(cbs, carddav_contact_created); - linphone_friend_list_cbs_set_contact_deleted(cbs, carddav_contact_deleted); - linphone_friend_list_cbs_set_contact_updated(cbs, carddav_contact_updated); - linphone_friend_list_cbs_set_sync_status_changed(cbs, carddav_sync_status_changed); - linphone_core_add_friend_list(manager->lc, lfl); - - BC_ASSERT_PTR_NULL(linphone_vcard_get_uid(lvc)); - BC_ASSERT_EQUAL(bctbx_list_size(lfl->dirty_friends_to_update), 0, int, "%d"); - BC_ASSERT_EQUAL(linphone_friend_list_add_friend(lfl, lf), LinphoneFriendListOK, int, "%d"); - BC_ASSERT_EQUAL(bctbx_list_size(lfl->dirty_friends_to_update), 1, int, "%d"); - wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 5000); - BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i"); - BC_ASSERT_EQUAL(bctbx_list_size(lfl->dirty_friends_to_update), 0, int, "%d"); - BC_ASSERT_PTR_NOT_NULL(linphone_vcard_get_uid(lvc)); - linphone_friend_list_remove_friend(lfl, lf); - BC_ASSERT_EQUAL(bctbx_list_size(lfl->friends), 0, int, "%d"); - wait_for_until(manager->lc, NULL, &stats->sync_done_count, 2, 5000); - BC_ASSERT_EQUAL(stats->sync_done_count, 2, int, "%i"); - linphone_friend_unref(lf); - lf = NULL; - - lvc = linphone_vcard_context_get_vcard_from_buffer(manager->lc->vcard_context, "BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Ghislain Mary\r\nIMPP;TYPE=work:sip:ghislain@sip.linphone.org\r\nEND:VCARD\r\n"); - lf = linphone_friend_new_from_vcard(lvc); - BC_ASSERT_EQUAL(linphone_friend_list_add_local_friend(lfl, lf), LinphoneFriendListOK, int, "%d"); - linphone_friend_unref(lf); - - lvc2 = linphone_vcard_context_get_vcard_from_buffer(manager->lc->vcard_context, "BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Sylvain Berfini\r\nIMPP:sip:sberfini@sip.linphone.org\r\nUID:1f08dd48-29ac-4097-8e48-8596d7776283\r\nEND:VCARD\r\n"); - linphone_vcard_set_url(lvc2, "/card.php/addressbooks/tester/default/me.vcf"); - lf2 = linphone_friend_new_from_vcard(lvc2); - linphone_friend_set_ref_key(lf2, refkey); - BC_ASSERT_EQUAL(linphone_friend_list_add_local_friend(lfl, lf2), LinphoneFriendListOK, int, "%d"); - - BC_ASSERT_EQUAL(lfl->revision, 0, int, "%i"); - linphone_friend_list_synchronize_friends_from_server(lfl); - wait_for_until(manager->lc, NULL, &stats->new_contact_count, 0, 5000); - BC_ASSERT_EQUAL(stats->new_contact_count, 0, int, "%i"); - wait_for_until(manager->lc, NULL, &stats->removed_contact_count, 1, 5000); - BC_ASSERT_EQUAL(stats->removed_contact_count, 1, int, "%i"); - wait_for_until(manager->lc, NULL, &stats->updated_contact_count, 1, 5000); - BC_ASSERT_EQUAL(stats->updated_contact_count, 1, int, "%i"); - BC_ASSERT_NOT_EQUAL(lfl->revision, 0, int, "%i"); - wait_for_until(manager->lc, NULL, &stats->sync_done_count, 3, 5000); - BC_ASSERT_EQUAL(stats->sync_done_count, 3, int, "%i"); - - BC_ASSERT_EQUAL(bctbx_list_size(lfl->friends), 1, int, "%i"); - lf = (LinphoneFriend *)lfl->friends->data; - BC_ASSERT_STRING_EQUAL(lf->refkey, refkey); - BC_ASSERT_EQUAL(lf->storage_id, lf2->storage_id, unsigned int, "%u"); - linphone_friend_unref(lf2); - addr = linphone_friend_get_address(lf); - address = linphone_address_as_string_uri_only(addr); - BC_ASSERT_STRING_EQUAL(address, "sip:sylvain@sip.linphone.org"); - ms_free(address); - linphone_address_unref(addr); - - linphone_friend_edit(lf); - linphone_friend_done(lf); - BC_ASSERT_EQUAL(bctbx_list_size(lf->friend_list->dirty_friends_to_update), 0, int, "%i"); - - linphone_core_set_network_reachable(manager->lc, FALSE); //To prevent the CardDAV update - linphone_friend_edit(lf); - linphone_friend_set_name(lf, "François Grisez"); - linphone_friend_done(lf); - BC_ASSERT_EQUAL(bctbx_list_size(lf->friend_list->dirty_friends_to_update), 1, int, "%i"); - - ms_free(stats); - linphone_friend_list_unref(lfl); - linphone_core_manager_destroy(manager); -} - -static void carddav_clean(void) { // This is to ensure the content of the test addressbook is in the correct state for the following tests - LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE); - LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc); - LinphoneFriendListCbs *cbs = linphone_friend_list_get_callbacks(lfl); - LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1); - bctbx_list_t *friends = NULL; - bctbx_list_t *friends_iterator = NULL; - LinphoneFriend *lf = NULL; - LinphoneVcard *lvc = NULL; - - linphone_friend_list_cbs_set_user_data(cbs, stats); - linphone_friend_list_cbs_set_contact_created(cbs, carddav_contact_created); - linphone_friend_list_cbs_set_contact_deleted(cbs, carddav_contact_deleted); - linphone_friend_list_cbs_set_contact_updated(cbs, carddav_contact_updated); - linphone_friend_list_cbs_set_sync_status_changed(cbs, carddav_sync_status_changed); - linphone_core_add_friend_list(manager->lc, lfl); - linphone_friend_list_set_uri(lfl, CARDDAV_SERVER); - - linphone_friend_list_synchronize_friends_from_server(lfl); - wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 5000); - BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i"); - stats->sync_done_count = 0; - - friends = bctbx_list_copy(lfl->friends); - friends_iterator = friends; - while (friends_iterator) { - LinphoneFriend *lf = (LinphoneFriend *)friends_iterator->data; - linphone_friend_list_remove_friend(lfl, lf); - wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 5000); - BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i"); - stats->sync_done_count = 0; - stats->removed_contact_count = 0; - friends_iterator = bctbx_list_next(friends_iterator); - } - bctbx_list_free(friends); - - lvc = linphone_vcard_context_get_vcard_from_buffer(manager->lc->vcard_context, "BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Sylvain Berfini\r\nIMPP:sip:sylvain@sip.linphone.org\r\nUID:1f08dd48-29ac-4097-8e48-8596d7776283\r\nEND:VCARD\r\n"); - linphone_vcard_set_url(lvc, "http://dav.linphone.org/card.php/addressbooks/tester/default/me.vcf"); - lf = linphone_friend_new_from_vcard(lvc); - linphone_friend_list_add_friend(lfl, lf); - wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 5000); - BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i"); - - ms_free(stats); - linphone_friend_unref(lf); - linphone_friend_list_unref(lfl); - linphone_core_manager_destroy(manager); -} - -static void carddav_multiple_sync(void) { - LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE); - LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc); - LinphoneFriendListCbs *cbs = linphone_friend_list_get_callbacks(lfl); - LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1); - - linphone_friend_list_cbs_set_user_data(cbs, stats); - linphone_friend_list_cbs_set_contact_created(cbs, carddav_contact_created); - linphone_friend_list_cbs_set_contact_deleted(cbs, carddav_contact_deleted); - linphone_friend_list_cbs_set_contact_updated(cbs, carddav_contact_updated); - linphone_friend_list_cbs_set_sync_status_changed(cbs, carddav_sync_status_changed); - linphone_core_add_friend_list(manager->lc, lfl); - linphone_friend_list_set_uri(lfl, CARDDAV_SERVER); - - linphone_friend_list_synchronize_friends_from_server(lfl); - wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 5000); - BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i"); - linphone_friend_list_synchronize_friends_from_server(lfl); - wait_for_until(manager->lc, NULL, &stats->sync_done_count, 2, 5000); - BC_ASSERT_EQUAL(stats->sync_done_count, 2, int, "%i"); - linphone_friend_list_synchronize_friends_from_server(lfl); - wait_for_until(manager->lc, NULL, &stats->sync_done_count, 3, 5000); - BC_ASSERT_EQUAL(stats->sync_done_count, 3, int, "%i"); - BC_ASSERT_EQUAL(stats->removed_contact_count, 0, int, "%i"); - - ms_free(stats); - linphone_friend_list_unref(lfl); - linphone_core_manager_destroy(manager); -} - -static void carddav_server_to_client_and_client_to_sever_sync(void) { - LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE); - LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc); - LinphoneFriendListCbs *cbs = linphone_friend_list_get_callbacks(lfl); - LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1); - LinphoneVcard *lvc1 = linphone_vcard_context_get_vcard_from_buffer(manager->lc->vcard_context, "BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Margaux Clerc\r\nIMPP;TYPE=work:sip:margaux@sip.linphone.org\r\nEND:VCARD\r\n"); - LinphoneFriend *lf1 = linphone_friend_new_from_vcard(lvc1); - LinphoneVcard *lvc2 = linphone_vcard_context_get_vcard_from_buffer(manager->lc->vcard_context, "BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Ghislain Mary\r\nIMPP;TYPE=work:sip:ghislain@sip.linphone.org\r\nEND:VCARD\r\n"); - LinphoneFriend *lf2 = linphone_friend_new_from_vcard(lvc2); - bctbx_list_t *friends = NULL, *friends_iterator = NULL; - - linphone_friend_list_cbs_set_user_data(cbs, stats); - linphone_friend_list_cbs_set_contact_created(cbs, carddav_contact_created); - linphone_friend_list_cbs_set_contact_deleted(cbs, carddav_contact_deleted); - linphone_friend_list_cbs_set_contact_updated(cbs, carddav_contact_updated); - linphone_friend_list_cbs_set_sync_status_changed(cbs, carddav_sync_status_changed); - linphone_core_add_friend_list(manager->lc, lfl); - linphone_friend_list_set_uri(lfl, CARDDAV_SERVER); - - linphone_friend_list_add_friend(lfl, lf1); - linphone_friend_unref(lf1); - linphone_friend_list_synchronize_friends_from_server(lfl); - linphone_friend_list_add_friend(lfl, lf2); - linphone_friend_unref(lf2); - wait_for_until(manager->lc, NULL, &stats->sync_done_count, 3, 15000); - BC_ASSERT_EQUAL(stats->sync_done_count, 3, int, "%i"); - - stats->sync_done_count = 0; - friends = bctbx_list_copy(lfl->friends); - friends_iterator = friends; - while (friends_iterator) { - LinphoneFriend *lf = (LinphoneFriend *)friends_iterator->data; - if (lf && strcmp(linphone_friend_get_name(lf), "Sylvain Berfini") != 0) { - linphone_friend_list_remove_friend(lfl, lf); - wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 5000); - BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i"); - stats->sync_done_count = 0; - } - friends_iterator = bctbx_list_next(friends_iterator); - } - bctbx_list_free(friends); - - ms_free(stats); - linphone_friend_list_unref(lfl); - linphone_core_manager_destroy(manager); -} - -test_t vcard_tests[] = { - TEST_NO_TAG("Import / Export friends from vCards", linphone_vcard_import_export_friends_test), - TEST_NO_TAG("Import a lot of friends from vCards", linphone_vcard_import_a_lot_of_friends_test), - TEST_NO_TAG("vCard creation for existing friends", linphone_vcard_update_existing_friends_test), - TEST_NO_TAG("vCard phone numbers and SIP addresses", linphone_vcard_phone_numbers_and_sip_addresses), -#ifdef SQLITE_STORAGE_ENABLED - TEST_ONE_TAG("Friends working if no db set", friends_if_no_db_set, "LeaksMemory"), - TEST_ONE_TAG("Friends storage migration from rc to db", friends_migration, "LeaksMemory"), - TEST_NO_TAG("Friends storage in sqlite database", friends_sqlite_storage), -#endif - TEST_NO_TAG("CardDAV clean", carddav_clean), // This is to ensure the content of the test addressbook is in the correct state for the following tests - TEST_NO_TAG("CardDAV synchronization", carddav_sync), - TEST_NO_TAG("CardDAV synchronization 2", carddav_sync_2), - TEST_NO_TAG("CardDAV synchronization 3", carddav_sync_3), - TEST_NO_TAG("CardDAV synchronization 4", carddav_sync_4), - TEST_NO_TAG("CardDAV integration", carddav_integration), - TEST_NO_TAG("CardDAV multiple synchronizations", carddav_multiple_sync), - TEST_NO_TAG("CardDAV client to server and server to client sync", carddav_server_to_client_and_client_to_sever_sync) -}; - -test_suite_t vcard_test_suite = { - "VCard", NULL, NULL, - liblinphone_tester_before_each, liblinphone_tester_after_each, - sizeof(vcard_tests) / sizeof(vcard_tests[0]), vcard_tests -}; - -#endif +/* + vcard_tester.c + Copyright (C) 2015 Belledonne Communications SARL + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifdef VCARD_ENABLED + +#include "linphonecore.h" +#include "private.h" +#include "liblinphone_tester.h" +#include "carddav.h" + +#include + +#define CARDDAV_SERVER "http://dav.linphone.org/card.php/addressbooks/tester/default" + +static void linphone_vcard_import_export_friends_test(void) { + LinphoneCoreManager* manager = linphone_core_manager_new2("empty_rc", FALSE); + LinphoneFriendList *lfl = linphone_core_get_default_friend_list(manager->lc); + const bctbx_list_t *friends = linphone_friend_list_get_friends(lfl); + char *import_filepath = bc_tester_res("vcards/vcards.vcf"); + char *export_filepath = bc_tester_file("export_vcards.vcf"); + int count = 0; + BC_ASSERT_EQUAL(bctbx_list_size(friends), 0, int, "%d"); + + count = linphone_friend_list_import_friends_from_vcard4_file(lfl, import_filepath); + BC_ASSERT_EQUAL(count, 3, int, "%d"); + friends = linphone_friend_list_get_friends(lfl); + BC_ASSERT_EQUAL(bctbx_list_size(friends), 3, int, "%d"); + + linphone_friend_list_export_friends_as_vcard4_file(lfl, export_filepath); + + lfl = linphone_core_create_friend_list(manager->lc); + count = linphone_friend_list_import_friends_from_vcard4_file(lfl, export_filepath); + BC_ASSERT_EQUAL(count, 3, int, "%d"); + friends = linphone_friend_list_get_friends(lfl); + BC_ASSERT_EQUAL(bctbx_list_size(friends), 3, int, "%d"); + linphone_friend_list_unref(lfl); + + remove(export_filepath); + ms_free(import_filepath); + ms_free(export_filepath); + linphone_core_manager_destroy(manager); +} + +static void linphone_vcard_import_a_lot_of_friends_test(void) { + LinphoneCoreManager* manager = linphone_core_manager_new2("empty_rc", FALSE); + LinphoneFriendList *lfl = linphone_core_get_default_friend_list(manager->lc); + char *import_filepath = bc_tester_res("vcards/thousand_vcards.vcf"); + clock_t start, end; + double elapsed = 0; + const bctbx_list_t *friends = NULL; + FILE *infile = NULL; + char *buffer = NULL; + long numbytes = 0; + + start = clock(); + linphone_friend_list_import_friends_from_vcard4_file(lfl, import_filepath); + end = clock(); + + friends = linphone_friend_list_get_friends(lfl); + BC_ASSERT_EQUAL(bctbx_list_size(friends), 1000, int, "%i"); // Now that we accept Friends without a SIP URI, the result must be equal to 1000 + + elapsed = (double)(end - start); + ms_error("Imported a thousand of vCards from file in %f seconds", (unsigned int)bctbx_list_size(friends), elapsed / CLOCKS_PER_SEC); + + lfl = linphone_core_create_friend_list(manager->lc); + infile = fopen(import_filepath, "rb"); + BC_ASSERT_PTR_NOT_NULL(infile); + if (infile) { + fseek(infile, 0L, SEEK_END); + numbytes = ftell(infile); + fseek(infile, 0L, SEEK_SET); + buffer = (char*)ms_malloc((numbytes + 1) * sizeof(char)); + numbytes = fread(buffer, sizeof(char), numbytes, infile); + fclose(infile); + buffer[numbytes] = '\0'; + + start = clock(); + linphone_friend_list_import_friends_from_vcard4_buffer(lfl, buffer); + end = clock(); + ms_free(buffer); + } + + friends = linphone_friend_list_get_friends(lfl); + BC_ASSERT_EQUAL(bctbx_list_size(friends), 1000, int, "%i"); // Now that we accept Friends without a SIP URI, the result must be equal to 1000 + + elapsed = (double)(end - start); + ms_error("Imported a thousand of vCards from buffer in %f seconds", (unsigned int)bctbx_list_size(friends), elapsed / CLOCKS_PER_SEC); + + linphone_friend_list_unref(lfl); + + ms_free(import_filepath); + linphone_core_manager_destroy(manager); +} + +#if __clang__ || ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4) +#pragma GCC diagnostic push +#endif +#ifdef _MSC_VER +#pragma warning(disable : 4996) +#else +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif + +static void linphone_vcard_update_existing_friends_test(void) { + LinphoneFriend *lf = linphone_friend_new_with_addr("sip:oldfriend@sip.linphone.org"); + + BC_ASSERT_PTR_NOT_NULL(lf); + if (linphone_core_vcard_supported()) { + BC_ASSERT_PTR_NOT_NULL(linphone_friend_get_vcard(lf)); + } else { + BC_ASSERT_PTR_NULL(linphone_friend_get_vcard(lf)); + } + + linphone_friend_edit(lf); + linphone_friend_set_name(lf, "Old Friend"); + linphone_friend_done(lf); + + BC_ASSERT_PTR_NOT_NULL(linphone_friend_get_vcard(lf)); + BC_ASSERT_STRING_EQUAL(linphone_vcard_get_full_name(linphone_friend_get_vcard(lf)), "Old Friend"); + linphone_friend_unref(lf); + lf = NULL; +} + +#if __clang__ || ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4) +#pragma GCC diagnostic pop +#endif + +static void linphone_vcard_phone_numbers_and_sip_addresses(void) { + LinphoneCoreManager* manager = linphone_core_manager_new2("empty_rc", FALSE); + LinphoneVcard *lvc = linphone_vcard_context_get_vcard_from_buffer(manager->lc->vcard_context, "BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Sylvain Berfini\r\nIMPP:sip:sberfini@sip.linphone.org\r\nIMPP;TYPE=home:sip:sylvain@sip.linphone.org\r\nTEL;TYPE=work:0952636505\r\nEND:VCARD\r\n"); + LinphoneFriend *lf = linphone_friend_new_from_vcard(lvc); + bctbx_list_t *sip_addresses = linphone_friend_get_addresses(lf); + bctbx_list_t *phone_numbers = linphone_friend_get_phone_numbers(lf); + LinphoneAddress *addr = NULL; + + BC_ASSERT_EQUAL(bctbx_list_size(sip_addresses), 2, int, "%i"); + BC_ASSERT_EQUAL(bctbx_list_size(phone_numbers), 1, int, "%i"); + if (sip_addresses) bctbx_list_free_with_data(sip_addresses, (void (*)(void *))linphone_address_unref); + if (phone_numbers) bctbx_list_free(phone_numbers); + linphone_friend_unref(lf); + + lvc = linphone_vcard_context_get_vcard_from_buffer(manager->lc->vcard_context, "BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Sylvain Berfini\r\nTEL;TYPE=work:0952636505\r\nTEL:0476010203\r\nEND:VCARD\r\n"); + lf = linphone_friend_new_from_vcard(lvc); + sip_addresses = linphone_friend_get_addresses(lf); + phone_numbers = linphone_friend_get_phone_numbers(lf); + + BC_ASSERT_EQUAL(bctbx_list_size(sip_addresses), 0, int, "%i"); + BC_ASSERT_EQUAL(bctbx_list_size(phone_numbers), 2, int, "%i"); + if (sip_addresses) bctbx_list_free_with_data(sip_addresses, (void (*)(void *))linphone_address_unref); + if (phone_numbers) bctbx_list_free(phone_numbers); + + addr = linphone_address_new("sip:sylvain@sip.linphone.org"); + linphone_friend_add_address(lf, addr); + linphone_address_unref(addr); + sip_addresses = linphone_friend_get_addresses(lf); + BC_ASSERT_EQUAL(bctbx_list_size(sip_addresses), 1, int, "%i"); + if (sip_addresses) bctbx_list_free_with_data(sip_addresses, (void (*)(void *))linphone_address_unref); + + linphone_friend_remove_phone_number(lf, "0952636505"); + phone_numbers = linphone_friend_get_phone_numbers(lf); + BC_ASSERT_EQUAL(bctbx_list_size(phone_numbers), 1, int, "%i"); + if (phone_numbers) bctbx_list_free(phone_numbers); + + linphone_friend_remove_phone_number(lf, "0476010203"); + phone_numbers = linphone_friend_get_phone_numbers(lf); + BC_ASSERT_EQUAL(bctbx_list_size(phone_numbers), 0, int, "%i"); + if (phone_numbers) bctbx_list_free(phone_numbers); + + addr = linphone_address_new("sip:sylvain@sip.linphone.org"); + linphone_friend_remove_address(lf, addr); + linphone_address_unref(addr); + sip_addresses = linphone_friend_get_addresses(lf); + BC_ASSERT_EQUAL(bctbx_list_size(sip_addresses), 0, int, "%i"); + if (sip_addresses) bctbx_list_free_with_data(sip_addresses, (void (*)(void *))linphone_address_unref); + + linphone_friend_add_phone_number(lf, "+33952636505"); + phone_numbers = linphone_friend_get_phone_numbers(lf); + BC_ASSERT_EQUAL(bctbx_list_size(phone_numbers), 1, int, "%i"); + if (phone_numbers) bctbx_list_free(phone_numbers); + + linphone_friend_unref(lf); + lf = NULL; + lvc = NULL; + linphone_core_manager_destroy(manager); +} + +#ifdef SQLITE_STORAGE_ENABLED +static void friends_if_no_db_set(void) { + LinphoneCoreManager* manager = linphone_core_manager_new2("empty_rc", FALSE); + LinphoneFriend *lf = linphone_core_create_friend(manager->lc); + LinphoneAddress *addr = linphone_address_new("sip:sylvain@sip.linphone.org"); + const bctbx_list_t *friends = NULL; + LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc); + + linphone_friend_set_address(lf, addr); + linphone_friend_set_name(lf, "Sylvain"); + linphone_friend_list_add_friend(lfl, lf); + friends = linphone_friend_list_get_friends(lfl); + BC_ASSERT_EQUAL(bctbx_list_size(friends), 1, int, "%d"); + + linphone_friend_list_remove_friend(lfl, lf); + linphone_friend_unref(lf); + friends = linphone_friend_list_get_friends(lfl); + BC_ASSERT_EQUAL(bctbx_list_size(friends), 0, int, "%d"); + + linphone_friend_list_unref(lfl); + linphone_address_unref(addr); + linphone_core_manager_destroy(manager); +} + +static void friends_migration(void) { + LinphoneCoreManager* manager = linphone_core_manager_new2("friends_rc", FALSE); + LpConfig *lpc = linphone_core_get_config(manager->lc); + LinphoneFriendList *lfl = linphone_core_get_default_friend_list(manager->lc); + const bctbx_list_t *friends = linphone_friend_list_get_friends(lfl); + bctbx_list_t *friends_from_db = NULL; + char *friends_db = bc_tester_file("friends.db"); + BC_ASSERT_EQUAL(bctbx_list_size(friends), 3, int, "%d"); + BC_ASSERT_EQUAL(lp_config_get_int(lpc, "misc", "friends_migration_done", 0), 0, int, "%i"); + + unlink(friends_db); + linphone_core_set_friends_database_path(manager->lc, friends_db); + lfl = linphone_core_get_default_friend_list(manager->lc); + friends = linphone_friend_list_get_friends(lfl); + BC_ASSERT_EQUAL(bctbx_list_size(friends), 3, int, "%d"); + friends_from_db = linphone_core_fetch_friends_from_db(manager->lc, lfl); + BC_ASSERT_EQUAL(bctbx_list_size(friends_from_db), 3, int, "%d"); + BC_ASSERT_EQUAL(lp_config_get_int(lpc, "misc", "friends_migration_done", 0), 1, int, "%i"); + + friends_from_db = bctbx_list_free_with_data(friends_from_db, (void (*)(void *))linphone_friend_unref); + unlink(friends_db); + ms_free(friends_db); + linphone_core_manager_destroy(manager); +} + +typedef struct _LinphoneFriendListStats { + int new_list_count; + int removed_list_count; +} LinphoneFriendListStats; + +static void friend_list_created_cb(LinphoneCore *lc, LinphoneFriendList *list) { + LinphoneFriendListStats *stats = (LinphoneFriendListStats *)linphone_friend_list_get_user_data(list); + if (stats) { + stats->new_list_count++; + } +} + +static void friend_list_removed_cb(LinphoneCore *lc, LinphoneFriendList *list) { + LinphoneFriendListStats *stats = (LinphoneFriendListStats *)linphone_friend_list_get_user_data(list); + if (stats) { + stats->removed_list_count++; + } +} + +static void friends_sqlite_storage(void) { + LinphoneCoreVTable *v_table = linphone_core_v_table_new(); + LinphoneCore* lc = NULL; + LinphoneFriendList *lfl = NULL; + LinphoneFriend *lf = NULL; + LinphoneFriend *lf2 = NULL; + LinphoneVcard *lvc = linphone_vcard_new(); + LinphoneAddress *addr = linphone_address_new("sip:sylvain@sip.linphone.org"); + const bctbx_list_t *friends = NULL; + bctbx_list_t *friends_from_db = NULL; + bctbx_list_t *friends_lists_from_db = NULL; + char *friends_db = bc_tester_file("friends.db"); + LinphoneFriendListStats *stats = (LinphoneFriendListStats *)ms_new0(LinphoneFriendListStats, 1); + LinphoneAddress *laddress = NULL, *laddress2 = NULL; + char *address = NULL, *address2 = NULL; + + v_table->friend_list_created = friend_list_created_cb; + v_table->friend_list_removed = friend_list_removed_cb; + lc = linphone_core_new(v_table, NULL, NULL, NULL); + friends = linphone_friend_list_get_friends(linphone_core_get_default_friend_list(lc)); + lfl = linphone_core_create_friend_list(lc); + linphone_friend_list_set_user_data(lfl, stats); + BC_ASSERT_EQUAL(bctbx_list_size(friends), 0, int, "%d"); + + unlink(friends_db); + linphone_core_set_friends_database_path(lc, friends_db); + friends_from_db = linphone_core_fetch_friends_from_db(lc, linphone_core_get_default_friend_list(lc)); + BC_ASSERT_EQUAL(bctbx_list_size(friends_from_db), 0, int, "%d"); + + linphone_vcard_set_etag(lvc, "\"123-456789\""); + linphone_vcard_set_url(lvc, "http://dav.somewhere.fr/addressbook/me/someone.vcf"); + lf = linphone_friend_new_from_vcard(lvc); + linphone_friend_set_address(lf, addr); + linphone_friend_set_name(lf, "Sylvain"); + + linphone_core_add_friend_list(lc, lfl); + wait_for_until(lc, NULL, &stats->new_list_count, 1, 1000); + BC_ASSERT_EQUAL(stats->new_list_count, 1, int, "%i"); + linphone_friend_list_unref(lfl); + linphone_friend_list_set_display_name(lfl, "Test"); + BC_ASSERT_EQUAL(linphone_friend_list_add_friend(lfl, lf), LinphoneFriendListOK, int, "%i"); + linphone_friend_unref(lf); + BC_ASSERT_EQUAL(lfl->storage_id, 1, unsigned int, "%u"); + BC_ASSERT_EQUAL(lf->storage_id, 1, unsigned int, "%u"); + + friends = linphone_friend_list_get_friends(linphone_core_get_default_friend_list(lc)); + BC_ASSERT_EQUAL(bctbx_list_size(friends), 0, int, "%d"); + + friends_lists_from_db = linphone_core_fetch_friends_lists_from_db(lc); + BC_ASSERT_EQUAL(bctbx_list_size(friends_lists_from_db), 1, int, "%d"); + friends_from_db = ((LinphoneFriendList *)friends_lists_from_db->data)->friends; + BC_ASSERT_EQUAL(bctbx_list_size(friends_from_db), 1, int, "%d"); + lf2 = (LinphoneFriend *)friends_from_db->data; + BC_ASSERT_PTR_NOT_NULL(lf2->lc); + BC_ASSERT_PTR_NOT_NULL(lf2->friend_list); + friends_lists_from_db = bctbx_list_free_with_data(friends_lists_from_db, (void (*)(void *))linphone_friend_list_unref); + + friends_from_db = linphone_core_fetch_friends_from_db(lc, lfl); + BC_ASSERT_EQUAL(bctbx_list_size(friends_from_db), 1, int, "%d"); + if (bctbx_list_size(friends_from_db) < 1) { + goto end; + } + lf2 = (LinphoneFriend *)friends_from_db->data; + BC_ASSERT_STRING_EQUAL(linphone_friend_get_name(lf2), linphone_friend_get_name(lf)); + BC_ASSERT_EQUAL(lf2->storage_id, lf->storage_id, unsigned int, "%u"); + BC_ASSERT_STRING_EQUAL(linphone_vcard_get_etag(linphone_friend_get_vcard(lf2)), linphone_vcard_get_etag(linphone_friend_get_vcard(lf))); + BC_ASSERT_STRING_EQUAL(linphone_vcard_get_url(linphone_friend_get_vcard(lf2)), linphone_vcard_get_url(linphone_friend_get_vcard(lf))); + laddress = linphone_friend_get_address(lf); + address = linphone_address_as_string(laddress); + laddress2 = linphone_friend_get_address(lf2); + address2 = linphone_address_as_string(laddress2); + BC_ASSERT_STRING_EQUAL(address2, address); + linphone_address_unref(laddress); + linphone_address_unref(laddress2); + ms_free(address); + ms_free(address2); + + linphone_friend_edit(lf); + linphone_friend_set_name(lf, "Margaux"); + linphone_friend_done(lf); + friends_from_db = bctbx_list_free_with_data(friends_from_db, (void (*)(void *))linphone_friend_unref); + friends_from_db = linphone_core_fetch_friends_from_db(lc, lfl); + BC_ASSERT_EQUAL(bctbx_list_size(friends_from_db), 1, int, "%d"); + if (bctbx_list_size(friends_from_db) < 1) { + goto end; + } + lf2 = (LinphoneFriend *)friends_from_db->data; + BC_ASSERT_STRING_EQUAL(linphone_friend_get_name(lf2), "Margaux"); + friends_from_db = bctbx_list_free_with_data(friends_from_db, (void (*)(void *))linphone_friend_unref); + + linphone_friend_list_remove_friend(lfl, lf); + friends = linphone_friend_list_get_friends(linphone_core_get_default_friend_list(lc)); + BC_ASSERT_EQUAL(bctbx_list_size(friends), 0, int, "%d"); + friends_from_db = linphone_core_fetch_friends_from_db(lc, lfl); + BC_ASSERT_EQUAL(bctbx_list_size(friends_from_db), 0, int, "%d"); + + linphone_core_remove_friend_list(lc, lfl); + wait_for_until(lc, NULL, &stats->removed_list_count, 1, 1000); + BC_ASSERT_EQUAL(stats->removed_list_count, 1, int, "%i"); + +end: + ms_free(stats); + unlink(friends_db); + ms_free(friends_db); + linphone_address_unref(addr); + linphone_core_destroy(lc); + linphone_core_v_table_destroy(v_table); +} +#endif + +typedef struct _LinphoneCardDAVStats { + int sync_done_count; + int new_contact_count; + int removed_contact_count; + int updated_contact_count; +} LinphoneCardDAVStats; + +static void carddav_sync_done(LinphoneCardDavContext *c, bool_t success, const char *message) { + LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_carddav_get_user_data(c); + BC_ASSERT_TRUE(success); + stats->sync_done_count++; +} + +static void carddav_new_contact(LinphoneCardDavContext *c, LinphoneFriend *lf) { + LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_carddav_get_user_data(c); + BC_ASSERT_PTR_NOT_NULL(lf); + stats->new_contact_count++; +} + +static void carddav_removed_contact(LinphoneCardDavContext *c, LinphoneFriend *lf) { + LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_carddav_get_user_data(c); + BC_ASSERT_PTR_NOT_NULL(lf); + stats->removed_contact_count++; +} + +static void carddav_updated_contact(LinphoneCardDavContext *c, LinphoneFriend *new_lf, LinphoneFriend *old_lf) { + LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_carddav_get_user_data(c); + BC_ASSERT_PTR_NOT_NULL(new_lf); + BC_ASSERT_PTR_NOT_NULL(old_lf); + stats->updated_contact_count++; +} + +static void carddav_sync(void) { + LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE); + LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1); + LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc); + LinphoneCardDavContext *c = NULL; + + linphone_friend_list_set_uri(lfl, CARDDAV_SERVER); + linphone_core_add_friend_list(manager->lc, lfl); + linphone_friend_list_unref(lfl); + c = linphone_carddav_context_new(lfl); + BC_ASSERT_PTR_NOT_NULL(c); + + linphone_carddav_set_user_data(c, stats); + linphone_carddav_set_synchronization_done_callback(c, carddav_sync_done); + linphone_carddav_set_new_contact_callback(c, carddav_new_contact); + linphone_carddav_set_removed_contact_callback(c, carddav_removed_contact); + linphone_carddav_set_updated_contact_callback(c, carddav_updated_contact); + linphone_carddav_synchronize(c); + + wait_for_until(manager->lc, NULL, &stats->new_contact_count, 1, 5000); + BC_ASSERT_EQUAL(stats->new_contact_count, 1, int, "%i"); + wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 5000); + BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i"); + + ms_free(stats); + linphone_carddav_context_destroy(c); + linphone_core_manager_destroy(manager); +} + +static void carddav_sync_2(void) { + LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE); + LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1); + LinphoneFriend *lf = linphone_core_create_friend_with_address(manager->lc, "\"Sylvain\" "); + char *friends_db = bc_tester_file("friends.db"); + LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc); + LinphoneCardDavContext *c = NULL; + + linphone_friend_list_set_uri(lfl, CARDDAV_SERVER); + linphone_core_add_friend_list(manager->lc, lfl); + linphone_friend_list_unref(lfl); + c = linphone_carddav_context_new(lfl); + BC_ASSERT_PTR_NOT_NULL(c); + + unlink(friends_db); + linphone_core_set_friends_database_path(manager->lc, friends_db); + BC_ASSERT_EQUAL(linphone_friend_list_add_local_friend(lfl, lf), LinphoneFriendListOK, int, "%d"); + linphone_friend_unref(lf); + + linphone_carddav_set_user_data(c, stats); + linphone_carddav_set_synchronization_done_callback(c, carddav_sync_done); + linphone_carddav_set_new_contact_callback(c, carddav_new_contact); + linphone_carddav_set_removed_contact_callback(c, carddav_removed_contact); + linphone_carddav_set_updated_contact_callback(c, carddav_updated_contact); + + linphone_carddav_synchronize(c); + + wait_for_until(manager->lc, NULL, &stats->new_contact_count, 1, 5000); + BC_ASSERT_EQUAL(stats->new_contact_count, 1, int, "%i"); + wait_for_until(manager->lc, NULL, &stats->removed_contact_count, 1, 5000); + BC_ASSERT_EQUAL(stats->removed_contact_count, 1, int, "%i"); + wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 5000); + BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i"); + + ms_free(stats); + unlink(friends_db); + ms_free(friends_db); + linphone_carddav_context_destroy(c); + linphone_core_manager_destroy(manager); +} + +static void carddav_sync_3(void) { + LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE); + LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1); + LinphoneVcard *lvc = linphone_vcard_context_get_vcard_from_buffer(manager->lc->vcard_context, "BEGIN:VCARD\r\nVERSION:4.0\r\nUID:1f08dd48-29ac-4097-8e48-8596d7776283\r\nFN:Sylvain Berfini\r\nIMPP;TYPE=work:sip:sylvain@sip.linphone.org\r\nEND:VCARD\r\n"); + LinphoneFriend *lf = linphone_friend_new_from_vcard(lvc); + char *friends_db = bc_tester_file("friends.db"); + LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc); + LinphoneCardDavContext *c = NULL; + + linphone_friend_list_set_uri(lfl, CARDDAV_SERVER); + linphone_core_add_friend_list(manager->lc, lfl); + linphone_friend_list_unref(lfl); + c = linphone_carddav_context_new(lfl); + BC_ASSERT_PTR_NOT_NULL(c); + + unlink(friends_db); + linphone_core_set_friends_database_path(manager->lc, friends_db); + BC_ASSERT_EQUAL(linphone_friend_list_add_local_friend(lfl, lf), LinphoneFriendListOK, int, "%d"); + linphone_friend_unref(lf); + + linphone_carddav_set_user_data(c, stats); + linphone_carddav_set_synchronization_done_callback(c, carddav_sync_done); + linphone_carddav_set_new_contact_callback(c, carddav_new_contact); + linphone_carddav_set_removed_contact_callback(c, carddav_removed_contact); + linphone_carddav_set_updated_contact_callback(c, carddav_updated_contact); + + linphone_carddav_synchronize(c); + + wait_for_until(manager->lc, NULL, &stats->updated_contact_count, 1, 5000); + BC_ASSERT_EQUAL(stats->updated_contact_count, 1, int, "%i"); + wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 5000); + BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i"); + + ms_free(stats); + unlink(friends_db); + ms_free(friends_db); + linphone_carddav_context_destroy(c); + c = NULL; + linphone_core_manager_destroy(manager); +} + +static void carddav_sync_4(void) { + LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE); + LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1); + LinphoneVcard *lvc = linphone_vcard_context_get_vcard_from_buffer(manager->lc->vcard_context, "BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Margaux Clerc\r\nIMPP;TYPE=work:sip:margaux@sip.linphone.org\r\nEND:VCARD\r\n"); + LinphoneFriend *lf = linphone_friend_new_from_vcard(lvc); + LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc); + LinphoneCardDavContext *c = NULL; + + linphone_friend_list_set_uri(lfl, CARDDAV_SERVER); + linphone_core_add_friend_list(manager->lc, lfl); + linphone_friend_list_unref(lfl); + c = linphone_carddav_context_new(lfl); + BC_ASSERT_PTR_NOT_NULL(c); + + linphone_carddav_set_user_data(c, stats); + linphone_carddav_set_synchronization_done_callback(c, carddav_sync_done); + linphone_carddav_set_new_contact_callback(c, carddav_new_contact); + linphone_carddav_set_removed_contact_callback(c, carddav_removed_contact); + linphone_carddav_set_updated_contact_callback(c, carddav_updated_contact); + + BC_ASSERT_PTR_NULL(linphone_vcard_get_uid(lvc)); + linphone_carddav_put_vcard(c, lf); + BC_ASSERT_PTR_NOT_NULL(linphone_vcard_get_uid(lvc)); + wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 5000); + BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i"); + + linphone_carddav_delete_vcard(c, lf); + wait_for_until(manager->lc, NULL, &stats->sync_done_count, 2, 5000); + BC_ASSERT_EQUAL(stats->sync_done_count, 2, int, "%i"); + + linphone_friend_unref(lf); + ms_free(stats); + linphone_carddav_context_destroy(c); + linphone_core_manager_destroy(manager); +} + +static void carddav_contact_created(LinphoneFriendList *list, LinphoneFriend *lf) { + LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_friend_list_cbs_get_user_data(list->cbs); + stats->new_contact_count++; +} + +static void carddav_contact_deleted(LinphoneFriendList *list, LinphoneFriend *lf) { + LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_friend_list_cbs_get_user_data(list->cbs); + stats->removed_contact_count++; +} + +static void carddav_contact_updated(LinphoneFriendList *list, LinphoneFriend *new_friend, LinphoneFriend *old_friend) { + LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_friend_list_cbs_get_user_data(list->cbs); + BC_ASSERT_STRING_EQUAL(linphone_vcard_get_full_name(linphone_friend_get_vcard(new_friend)), linphone_vcard_get_full_name(linphone_friend_get_vcard(old_friend))); + stats->updated_contact_count++; +} + +static void carddav_sync_status_changed(LinphoneFriendList *list, LinphoneFriendListSyncStatus status, const char *msg) { + LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_friend_list_cbs_get_user_data(list->cbs); + char *state = status == LinphoneFriendListSyncStarted ? "Sync started" : (status == LinphoneFriendListSyncFailure ? "Sync failure" : "Sync successful"); + ms_message("[CardDAV] %s : %s", state, msg); + if (status == LinphoneFriendListSyncFailure || status == LinphoneFriendListSyncSuccessful) { + stats->sync_done_count++; + } +} + +static void carddav_integration(void) { + LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE); + LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc); + LinphoneVcard *lvc = linphone_vcard_context_get_vcard_from_buffer(manager->lc->vcard_context, "BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Margaux Clerc\r\nIMPP;TYPE=work:sip:margaux@sip.linphone.org\r\nEND:VCARD\r\n"); + LinphoneFriend *lf = linphone_friend_new_from_vcard(lvc); + LinphoneVcard *lvc2 = NULL; + LinphoneFriend *lf2 = NULL; + LinphoneFriendListCbs *cbs = NULL; + LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1); + const char *refkey = "toto"; + char *address = NULL; + LinphoneAddress *addr; + + linphone_friend_list_set_uri(lfl, CARDDAV_SERVER); + cbs = linphone_friend_list_get_callbacks(lfl); + linphone_friend_list_cbs_set_user_data(cbs, stats); + linphone_friend_list_cbs_set_contact_created(cbs, carddav_contact_created); + linphone_friend_list_cbs_set_contact_deleted(cbs, carddav_contact_deleted); + linphone_friend_list_cbs_set_contact_updated(cbs, carddav_contact_updated); + linphone_friend_list_cbs_set_sync_status_changed(cbs, carddav_sync_status_changed); + linphone_core_add_friend_list(manager->lc, lfl); + + BC_ASSERT_PTR_NULL(linphone_vcard_get_uid(lvc)); + BC_ASSERT_EQUAL(bctbx_list_size(lfl->dirty_friends_to_update), 0, int, "%d"); + BC_ASSERT_EQUAL(linphone_friend_list_add_friend(lfl, lf), LinphoneFriendListOK, int, "%d"); + BC_ASSERT_EQUAL(bctbx_list_size(lfl->dirty_friends_to_update), 1, int, "%d"); + wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 5000); + BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i"); + BC_ASSERT_EQUAL(bctbx_list_size(lfl->dirty_friends_to_update), 0, int, "%d"); + BC_ASSERT_PTR_NOT_NULL(linphone_vcard_get_uid(lvc)); + linphone_friend_list_remove_friend(lfl, lf); + BC_ASSERT_EQUAL(bctbx_list_size(lfl->friends), 0, int, "%d"); + wait_for_until(manager->lc, NULL, &stats->sync_done_count, 2, 5000); + BC_ASSERT_EQUAL(stats->sync_done_count, 2, int, "%i"); + linphone_friend_unref(lf); + lf = NULL; + + lvc = linphone_vcard_context_get_vcard_from_buffer(manager->lc->vcard_context, "BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Ghislain Mary\r\nIMPP;TYPE=work:sip:ghislain@sip.linphone.org\r\nEND:VCARD\r\n"); + lf = linphone_friend_new_from_vcard(lvc); + BC_ASSERT_EQUAL(linphone_friend_list_add_local_friend(lfl, lf), LinphoneFriendListOK, int, "%d"); + linphone_friend_unref(lf); + + lvc2 = linphone_vcard_context_get_vcard_from_buffer(manager->lc->vcard_context, "BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Sylvain Berfini\r\nIMPP:sip:sberfini@sip.linphone.org\r\nUID:1f08dd48-29ac-4097-8e48-8596d7776283\r\nEND:VCARD\r\n"); + linphone_vcard_set_url(lvc2, "/card.php/addressbooks/tester/default/me.vcf"); + lf2 = linphone_friend_new_from_vcard(lvc2); + linphone_friend_set_ref_key(lf2, refkey); + BC_ASSERT_EQUAL(linphone_friend_list_add_local_friend(lfl, lf2), LinphoneFriendListOK, int, "%d"); + + BC_ASSERT_EQUAL(lfl->revision, 0, int, "%i"); + linphone_friend_list_synchronize_friends_from_server(lfl); + wait_for_until(manager->lc, NULL, &stats->new_contact_count, 0, 5000); + BC_ASSERT_EQUAL(stats->new_contact_count, 0, int, "%i"); + wait_for_until(manager->lc, NULL, &stats->removed_contact_count, 1, 5000); + BC_ASSERT_EQUAL(stats->removed_contact_count, 1, int, "%i"); + wait_for_until(manager->lc, NULL, &stats->updated_contact_count, 1, 5000); + BC_ASSERT_EQUAL(stats->updated_contact_count, 1, int, "%i"); + BC_ASSERT_NOT_EQUAL(lfl->revision, 0, int, "%i"); + wait_for_until(manager->lc, NULL, &stats->sync_done_count, 3, 5000); + BC_ASSERT_EQUAL(stats->sync_done_count, 3, int, "%i"); + + BC_ASSERT_EQUAL(bctbx_list_size(lfl->friends), 1, int, "%i"); + lf = (LinphoneFriend *)lfl->friends->data; + BC_ASSERT_STRING_EQUAL(lf->refkey, refkey); + BC_ASSERT_EQUAL(lf->storage_id, lf2->storage_id, unsigned int, "%u"); + linphone_friend_unref(lf2); + addr = linphone_friend_get_address(lf); + address = linphone_address_as_string_uri_only(addr); + BC_ASSERT_STRING_EQUAL(address, "sip:sylvain@sip.linphone.org"); + ms_free(address); + linphone_address_unref(addr); + + linphone_friend_edit(lf); + linphone_friend_done(lf); + BC_ASSERT_EQUAL(bctbx_list_size(lf->friend_list->dirty_friends_to_update), 0, int, "%i"); + + linphone_core_set_network_reachable(manager->lc, FALSE); //To prevent the CardDAV update + linphone_friend_edit(lf); + linphone_friend_set_name(lf, "François Grisez"); + linphone_friend_done(lf); + BC_ASSERT_EQUAL(bctbx_list_size(lf->friend_list->dirty_friends_to_update), 1, int, "%i"); + + ms_free(stats); + linphone_friend_list_unref(lfl); + linphone_core_manager_destroy(manager); +} + +static void carddav_clean(void) { // This is to ensure the content of the test addressbook is in the correct state for the following tests + LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE); + LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc); + LinphoneFriendListCbs *cbs = linphone_friend_list_get_callbacks(lfl); + LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1); + bctbx_list_t *friends = NULL; + bctbx_list_t *friends_iterator = NULL; + LinphoneFriend *lf = NULL; + LinphoneVcard *lvc = NULL; + + linphone_friend_list_cbs_set_user_data(cbs, stats); + linphone_friend_list_cbs_set_contact_created(cbs, carddav_contact_created); + linphone_friend_list_cbs_set_contact_deleted(cbs, carddav_contact_deleted); + linphone_friend_list_cbs_set_contact_updated(cbs, carddav_contact_updated); + linphone_friend_list_cbs_set_sync_status_changed(cbs, carddav_sync_status_changed); + linphone_core_add_friend_list(manager->lc, lfl); + linphone_friend_list_set_uri(lfl, CARDDAV_SERVER); + + linphone_friend_list_synchronize_friends_from_server(lfl); + wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 5000); + BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i"); + stats->sync_done_count = 0; + + friends = bctbx_list_copy(lfl->friends); + friends_iterator = friends; + while (friends_iterator) { + LinphoneFriend *lf = (LinphoneFriend *)friends_iterator->data; + linphone_friend_list_remove_friend(lfl, lf); + wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 5000); + BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i"); + stats->sync_done_count = 0; + stats->removed_contact_count = 0; + friends_iterator = bctbx_list_next(friends_iterator); + } + bctbx_list_free(friends); + + lvc = linphone_vcard_context_get_vcard_from_buffer(manager->lc->vcard_context, "BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Sylvain Berfini\r\nIMPP:sip:sylvain@sip.linphone.org\r\nUID:1f08dd48-29ac-4097-8e48-8596d7776283\r\nEND:VCARD\r\n"); + linphone_vcard_set_url(lvc, "http://dav.linphone.org/card.php/addressbooks/tester/default/me.vcf"); + lf = linphone_friend_new_from_vcard(lvc); + linphone_friend_list_add_friend(lfl, lf); + wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 5000); + BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i"); + + ms_free(stats); + linphone_friend_unref(lf); + linphone_friend_list_unref(lfl); + linphone_core_manager_destroy(manager); +} + +static void carddav_multiple_sync(void) { + LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE); + LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc); + LinphoneFriendListCbs *cbs = linphone_friend_list_get_callbacks(lfl); + LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1); + + linphone_friend_list_cbs_set_user_data(cbs, stats); + linphone_friend_list_cbs_set_contact_created(cbs, carddav_contact_created); + linphone_friend_list_cbs_set_contact_deleted(cbs, carddav_contact_deleted); + linphone_friend_list_cbs_set_contact_updated(cbs, carddav_contact_updated); + linphone_friend_list_cbs_set_sync_status_changed(cbs, carddav_sync_status_changed); + linphone_core_add_friend_list(manager->lc, lfl); + linphone_friend_list_set_uri(lfl, CARDDAV_SERVER); + + linphone_friend_list_synchronize_friends_from_server(lfl); + wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 5000); + BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i"); + linphone_friend_list_synchronize_friends_from_server(lfl); + wait_for_until(manager->lc, NULL, &stats->sync_done_count, 2, 5000); + BC_ASSERT_EQUAL(stats->sync_done_count, 2, int, "%i"); + linphone_friend_list_synchronize_friends_from_server(lfl); + wait_for_until(manager->lc, NULL, &stats->sync_done_count, 3, 5000); + BC_ASSERT_EQUAL(stats->sync_done_count, 3, int, "%i"); + BC_ASSERT_EQUAL(stats->removed_contact_count, 0, int, "%i"); + + ms_free(stats); + linphone_friend_list_unref(lfl); + linphone_core_manager_destroy(manager); +} + +static void carddav_server_to_client_and_client_to_sever_sync(void) { + LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE); + LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc); + LinphoneFriendListCbs *cbs = linphone_friend_list_get_callbacks(lfl); + LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1); + LinphoneVcard *lvc1 = linphone_vcard_context_get_vcard_from_buffer(manager->lc->vcard_context, "BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Margaux Clerc\r\nIMPP;TYPE=work:sip:margaux@sip.linphone.org\r\nEND:VCARD\r\n"); + LinphoneFriend *lf1 = linphone_friend_new_from_vcard(lvc1); + LinphoneVcard *lvc2 = linphone_vcard_context_get_vcard_from_buffer(manager->lc->vcard_context, "BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Ghislain Mary\r\nIMPP;TYPE=work:sip:ghislain@sip.linphone.org\r\nEND:VCARD\r\n"); + LinphoneFriend *lf2 = linphone_friend_new_from_vcard(lvc2); + bctbx_list_t *friends = NULL, *friends_iterator = NULL; + + linphone_friend_list_cbs_set_user_data(cbs, stats); + linphone_friend_list_cbs_set_contact_created(cbs, carddav_contact_created); + linphone_friend_list_cbs_set_contact_deleted(cbs, carddav_contact_deleted); + linphone_friend_list_cbs_set_contact_updated(cbs, carddav_contact_updated); + linphone_friend_list_cbs_set_sync_status_changed(cbs, carddav_sync_status_changed); + linphone_core_add_friend_list(manager->lc, lfl); + linphone_friend_list_set_uri(lfl, CARDDAV_SERVER); + + linphone_friend_list_add_friend(lfl, lf1); + linphone_friend_unref(lf1); + linphone_friend_list_synchronize_friends_from_server(lfl); + linphone_friend_list_add_friend(lfl, lf2); + linphone_friend_unref(lf2); + wait_for_until(manager->lc, NULL, &stats->sync_done_count, 3, 15000); + BC_ASSERT_EQUAL(stats->sync_done_count, 3, int, "%i"); + + stats->sync_done_count = 0; + friends = bctbx_list_copy(lfl->friends); + friends_iterator = friends; + while (friends_iterator) { + LinphoneFriend *lf = (LinphoneFriend *)friends_iterator->data; + if (lf && strcmp(linphone_friend_get_name(lf), "Sylvain Berfini") != 0) { + linphone_friend_list_remove_friend(lfl, lf); + wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 5000); + BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i"); + stats->sync_done_count = 0; + } + friends_iterator = bctbx_list_next(friends_iterator); + } + bctbx_list_free(friends); + + ms_free(stats); + linphone_friend_list_unref(lfl); + linphone_core_manager_destroy(manager); +} + +test_t vcard_tests[] = { + TEST_NO_TAG("Import / Export friends from vCards", linphone_vcard_import_export_friends_test), + TEST_NO_TAG("Import a lot of friends from vCards", linphone_vcard_import_a_lot_of_friends_test), + TEST_NO_TAG("vCard creation for existing friends", linphone_vcard_update_existing_friends_test), + TEST_NO_TAG("vCard phone numbers and SIP addresses", linphone_vcard_phone_numbers_and_sip_addresses), +#ifdef SQLITE_STORAGE_ENABLED + TEST_ONE_TAG("Friends working if no db set", friends_if_no_db_set, "LeaksMemory"), + TEST_ONE_TAG("Friends storage migration from rc to db", friends_migration, "LeaksMemory"), + TEST_NO_TAG("Friends storage in sqlite database", friends_sqlite_storage), +#endif + TEST_NO_TAG("CardDAV clean", carddav_clean), // This is to ensure the content of the test addressbook is in the correct state for the following tests + TEST_NO_TAG("CardDAV synchronization", carddav_sync), + TEST_NO_TAG("CardDAV synchronization 2", carddav_sync_2), + TEST_NO_TAG("CardDAV synchronization 3", carddav_sync_3), + TEST_NO_TAG("CardDAV synchronization 4", carddav_sync_4), + TEST_NO_TAG("CardDAV integration", carddav_integration), + TEST_NO_TAG("CardDAV multiple synchronizations", carddav_multiple_sync), + TEST_NO_TAG("CardDAV client to server and server to client sync", carddav_server_to_client_and_client_to_sever_sync) +}; + +test_suite_t vcard_test_suite = { + "VCard", NULL, NULL, + liblinphone_tester_before_each, liblinphone_tester_after_each, + sizeof(vcard_tests) / sizeof(vcard_tests[0]), vcard_tests +}; + +#endif