From 5574b7ec7381dfa6cfef8b316dfc2a6473ed3371 Mon Sep 17 00:00:00 2001 From: Erwan Croze Date: Fri, 16 Feb 2018 15:16:56 +0100 Subject: [PATCH] Finishing search api --- coreapi/friend.c | 2 +- include/linphone/api/c-magic-search.h | 18 ++- include/linphone/api/c-search-result.h | 6 +- include/linphone/friend.h | 2 +- src/c-wrapper/api/c-magic-search.cpp | 14 +- src/c-wrapper/api/c-search-result.cpp | 6 +- src/search/magic-search-p.h | 2 + src/search/magic-search.cpp | 188 ++++++++++++++++++------- src/search/magic-search.h | 63 ++++++++- src/search/search-result.cpp | 12 +- src/search/search-result.h | 6 +- tester/setup_tester.c | 139 ++++++++++++++++-- 12 files changed, 380 insertions(+), 78 deletions(-) diff --git a/coreapi/friend.c b/coreapi/friend.c index f5d915a4a..a427db250 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -413,7 +413,7 @@ void linphone_friend_add_phone_number(LinphoneFriend *lf, const char *phone) { } } -bctbx_list_t* linphone_friend_get_phone_numbers(LinphoneFriend *lf) { +bctbx_list_t* linphone_friend_get_phone_numbers(const LinphoneFriend *lf) { if (!lf || !lf->vcard) return NULL; if (linphone_core_vcard_supported()) { diff --git a/include/linphone/api/c-magic-search.h b/include/linphone/api/c-magic-search.h index 6637b64e8..a26f6e7fc 100644 --- a/include/linphone/api/c-magic-search.h +++ b/include/linphone/api/c-magic-search.h @@ -79,6 +79,17 @@ LINPHONE_PUBLIC const char *linphone_magic_search_get_delimiter(const LinphoneMa **/ LINPHONE_PUBLIC void linphone_magic_search_set_delimiter(LinphoneMagicSearch *magicSearch, const char *delimiter); +/** + * @return if the delimiter search is used + **/ +LINPHONE_PUBLIC bool_t linphone_magic_search_get_use_delimiter(LinphoneMagicSearch *magicSearch); + +/** + * Enable or disable the delimiter in search + * @param[in] enable + **/ +LINPHONE_PUBLIC void linphone_magic_search_set_use_delimiter(LinphoneMagicSearch *magicSearch, bool_t enable); + /** * @return the number of the maximum SearchResult which will be return **/ @@ -101,6 +112,11 @@ LINPHONE_PUBLIC bool_t linphone_magic_search_get_limited_search(const LinphoneMa **/ LINPHONE_PUBLIC void linphone_magic_search_set_limited_search(LinphoneMagicSearch *magicSearch, const bool_t limited); +/** + * Reset the cache to begin a new search + **/ +LINPHONE_PUBLIC void linphone_magic_search_reset_search_cache(LinphoneMagicSearch *magicSearch); + /** * Create a sorted list of SearchResult from SipUri, Contact name, * Contact displayname, Contact phone number, which match with a filter word @@ -108,7 +124,7 @@ LINPHONE_PUBLIC void linphone_magic_search_set_limited_search(LinphoneMagicSearc * @param[in] withDomain domain which we want to search only * @return sorted list of \bctbx_list{LinphoneSearchResult} **/ -LINPHONE_PUBLIC bctbx_list_t* linphone_magic_search_get_contact_list_from_filter(const LinphoneMagicSearch *magicSearch, const char *filter, const char *withDomain); +LINPHONE_PUBLIC bctbx_list_t* linphone_magic_search_get_contact_list_from_filter(LinphoneMagicSearch *magicSearch, const char *filter, const char *withDomain); /** * @} diff --git a/include/linphone/api/c-search-result.h b/include/linphone/api/c-search-result.h index 98b858993..7a4a62485 100644 --- a/include/linphone/api/c-search-result.h +++ b/include/linphone/api/c-search-result.h @@ -44,17 +44,17 @@ LINPHONE_PUBLIC void linphone_search_result_unref(LinphoneSearchResult *searchRe /** * @return LinphoneFriend associed **/ -LINPHONE_PUBLIC const LinphoneFriend* linphone_search_result_get_friend(LinphoneSearchResult *searchResult); +LINPHONE_PUBLIC const LinphoneFriend* linphone_search_result_get_friend(const LinphoneSearchResult *searchResult); /** * @return LinphoneAddress associed **/ -LINPHONE_PUBLIC const LinphoneAddress* linphone_search_result_get_address(LinphoneSearchResult *searchResult); +LINPHONE_PUBLIC const LinphoneAddress* linphone_search_result_get_address(const LinphoneSearchResult *searchResult); /** * @return the result weight **/ -LINPHONE_PUBLIC unsigned int linphone_search_result_get_weight(LinphoneSearchResult *searchResult); +LINPHONE_PUBLIC unsigned int linphone_search_result_get_weight(const LinphoneSearchResult *searchResult); /** * @} diff --git a/include/linphone/friend.h b/include/linphone/friend.h index b4edf3835..6daca4a15 100644 --- a/include/linphone/friend.h +++ b/include/linphone/friend.h @@ -116,7 +116,7 @@ LINPHONE_PUBLIC void linphone_friend_add_phone_number(LinphoneFriend *lf, const * @param lf #LinphoneFriend object * @return \bctbx_list{const char *} */ -LINPHONE_PUBLIC bctbx_list_t* linphone_friend_get_phone_numbers(LinphoneFriend *lf); +LINPHONE_PUBLIC bctbx_list_t* linphone_friend_get_phone_numbers(const LinphoneFriend *lf); /** * Removes a phone number in this friend diff --git a/src/c-wrapper/api/c-magic-search.cpp b/src/c-wrapper/api/c-magic-search.cpp index 0a01e99fc..7716080dc 100644 --- a/src/c-wrapper/api/c-magic-search.cpp +++ b/src/c-wrapper/api/c-magic-search.cpp @@ -65,6 +65,14 @@ void linphone_magic_search_set_delimiter(LinphoneMagicSearch *magicSearch, const L_GET_CPP_PTR_FROM_C_OBJECT(magicSearch)->setDelimiter(L_C_TO_STRING(delimiter)); } +bool_t linphone_magic_search_get_use_delimiter(LinphoneMagicSearch *magicSearch) { + return L_GET_CPP_PTR_FROM_C_OBJECT(magicSearch)->getUseDelimiter(); +} + +void linphone_magic_search_set_use_delimiter(LinphoneMagicSearch *magicSearch, bool_t enable) { + L_GET_CPP_PTR_FROM_C_OBJECT(magicSearch)->setUseDelimiter(enable); +} + unsigned int linphone_magic_search_get_search_limit(const LinphoneMagicSearch *magicSearch) { return L_GET_CPP_PTR_FROM_C_OBJECT(magicSearch)->getSearchLimit(); } @@ -81,6 +89,10 @@ void linphone_magic_search_set_limited_search(LinphoneMagicSearch *magicSearch, L_GET_CPP_PTR_FROM_C_OBJECT(magicSearch)->setLimitedSearch(limited); } -bctbx_list_t* linphone_magic_search_get_contact_list_from_filter(const LinphoneMagicSearch *magicSearch, const char *filter, const char *withDomain) { +void linphone_magic_search_reset_search_cache(LinphoneMagicSearch *magicSearch) { + L_GET_CPP_PTR_FROM_C_OBJECT(magicSearch)->resetSearchCache(); +} + +bctbx_list_t* linphone_magic_search_get_contact_list_from_filter(LinphoneMagicSearch *magicSearch, const char *filter, const char *withDomain) { return L_GET_RESOLVED_C_LIST_FROM_CPP_LIST(L_GET_CPP_PTR_FROM_C_OBJECT(magicSearch)->getContactListFromFilter(L_C_TO_STRING(filter), L_C_TO_STRING(withDomain))); } diff --git a/src/c-wrapper/api/c-search-result.cpp b/src/c-wrapper/api/c-search-result.cpp index 5fb8ed578..77cd38c13 100644 --- a/src/c-wrapper/api/c-search-result.cpp +++ b/src/c-wrapper/api/c-search-result.cpp @@ -31,14 +31,14 @@ void linphone_search_result_unref(LinphoneSearchResult *searchResult) { belle_sip_object_unref(searchResult); } -const LinphoneFriend* linphone_search_result_get_friend(LinphoneSearchResult *searchResult) { +const LinphoneFriend* linphone_search_result_get_friend(const LinphoneSearchResult *searchResult) { return L_GET_CPP_PTR_FROM_C_OBJECT(searchResult)->getFriend(); } -const LinphoneAddress* linphone_search_result_get_address(LinphoneSearchResult *searchResult) { +const LinphoneAddress* linphone_search_result_get_address(const LinphoneSearchResult *searchResult) { return L_GET_CPP_PTR_FROM_C_OBJECT(searchResult)->getAddress(); } -unsigned int linphone_search_result_get_weight(LinphoneSearchResult *searchResult) { +unsigned int linphone_search_result_get_weight(const LinphoneSearchResult *searchResult) { return L_GET_CPP_PTR_FROM_C_OBJECT(searchResult)->getWeight(); } diff --git a/src/search/magic-search-p.h b/src/search/magic-search-p.h index b22bda379..0a75e5cab 100644 --- a/src/search/magic-search-p.h +++ b/src/search/magic-search-p.h @@ -32,6 +32,8 @@ private: unsigned int mSearchLimit; // Number of ResultSearch maximum when the search is limited bool mLimitedSearch; // Limit the search std::string mDelimiter; // Delimiter use for the search + bool mUseDelimiter; + std::list *mCacheResult; L_DECLARE_PUBLIC(MagicSearch); }; diff --git a/src/search/magic-search.cpp b/src/search/magic-search.cpp index 67932583a..663877665 100644 --- a/src/search/magic-search.cpp +++ b/src/search/magic-search.cpp @@ -38,6 +38,12 @@ MagicSearch::MagicSearch(const std::shared_ptr &core) : CoreAccessor(core) d->mSearchLimit = 10; d->mLimitedSearch = true; d->mDelimiter = "+_-"; + d->mUseDelimiter = true; + d->mCacheResult = nullptr; +} + +MagicSearch::~MagicSearch() { + resetSearchCache(); } void MagicSearch::setMinWeight(const unsigned int weight) { @@ -70,6 +76,16 @@ void MagicSearch::setDelimiter(const string &delimiter) { d->mDelimiter = delimiter; } +bool MagicSearch::getUseDelimiter() const { + L_D(); + return d->mUseDelimiter; +} + +void MagicSearch::setUseDelimiter(bool enable) { + L_D(); + d->mUseDelimiter = enable; +} + unsigned int MagicSearch::getSearchLimit() const { L_D(); return d->mSearchLimit; @@ -90,85 +106,153 @@ void MagicSearch::setLimitedSearch(const bool limited) { d->mLimitedSearch = limited; } -list MagicSearch::getContactListFromFilter(const string &filter, const string &withDomain) const { - list resultList = list(); +void MagicSearch::resetSearchCache() { + L_D(); + if (d->mCacheResult) { + delete d->mCacheResult; + d->mCacheResult = nullptr; + } +} + +list MagicSearch::getContactListFromFilter(const string &filter, const string &withDomain) { + list *resultList; + + if (filter.empty()) return list(); + + if (getSearchCache() != nullptr) { + resultList = continueSearch(filter, withDomain); + } else { + resultList = beginNewSearch(filter, withDomain); + } + + resultList->sort([](const SearchResult& lsr, const SearchResult& rsr){ + return lsr >= rsr; + }); + + setSearchCache(resultList); + + return *resultList; +} + +///////////////////// +// Private Methods // +///////////////////// + +list *MagicSearch::getSearchCache() const { + L_D(); + return d->mCacheResult; +} + +void MagicSearch::setSearchCache(list *cache) { + L_D(); + if (d->mCacheResult != cache) resetSearchCache(); + d->mCacheResult = cache; +} + +list *MagicSearch::beginNewSearch(const string &filter, const string &withDomain) { + list *resultList = new list(); LinphoneFriendList* list = linphone_core_get_default_friend_list(this->getCore()->getCCore()); // For all friends or when we reach the search limit - for (bctbx_list_t *f = list->friends ; - f != nullptr && (!getLimitedSearch() || resultList.size() < getSearchLimit()); - f = bctbx_list_next(f) - ) { - unsigned int weight = getMinWeight(); - LinphoneFriend* lFriend = reinterpret_cast(f->data); - const LinphoneAddress* lAddress = linphone_friend_get_address(lFriend); - - if (lAddress == nullptr) break; - - // Check domain - if (!withDomain.empty() && - withDomain.compare(linphone_address_get_domain(lAddress)) != 0 - ) break; - - // NAME - if (linphone_friend_get_name(lFriend) != nullptr) { - weight += getWeight(linphone_friend_get_name(lFriend), filter); + for (bctbx_list_t *f = list->friends; + f != nullptr && (!getLimitedSearch() || resultList->size() < getSearchLimit()); + f = bctbx_list_next(f) + ) { + SearchResult result = search(reinterpret_cast(f->data), filter, withDomain); + if (result.getWeight() > getMinWeight()) { + resultList->push_back(result); } - - // PHONE NUMBER - bctbx_list_t *phoneNumbers = linphone_friend_get_phone_numbers(lFriend); - while (phoneNumbers != nullptr && phoneNumbers->data != nullptr) { - string number = static_cast(phoneNumbers->data); - weight += getWeight(number, filter); - phoneNumbers = phoneNumbers->next; - } - - // SIPURI - if (linphone_address_get_username(lAddress) != nullptr) { - weight += getWeight(linphone_address_get_username(lAddress), filter); - } - - - // DISPLAYNAME - if (linphone_address_get_display_name(lAddress) != nullptr) { - weight += getWeight(linphone_address_get_display_name(lAddress), filter); - } - - resultList.push_back(SearchResult(weight, lAddress, lFriend)); } - resultList.sort(); + return resultList; +} + +list *MagicSearch::continueSearch(const string &filter, const string &withDomain) { + list *resultList = new list(); + const list *cacheList = getSearchCache(); + + for (const auto sr : *cacheList) { + if (sr.getFriend()) { + SearchResult result = search(sr.getFriend(), filter, withDomain); + if (result.getWeight() > getMinWeight()) { + resultList->push_back(result); + } + } + } return resultList; } +SearchResult MagicSearch::search(const LinphoneFriend* lFriend, const string &filter, const string &withDomain) { + unsigned int weight = getMinWeight(); + const LinphoneAddress* lAddress = linphone_friend_get_address(lFriend); + + if (lAddress == nullptr) return SearchResult(weight, nullptr); + + // Check domain + if (!withDomain.empty() && + withDomain.compare(linphone_address_get_domain(lAddress)) != 0 + ) return SearchResult(weight, nullptr); + + // NAME + if (linphone_friend_get_name(lFriend) != nullptr) { + weight += getWeight(linphone_friend_get_name(lFriend), filter); + } + + // PHONE NUMBER + bctbx_list_t *phoneNumbers = linphone_friend_get_phone_numbers(lFriend); + while (phoneNumbers != nullptr && phoneNumbers->data != nullptr) { + string number = static_cast(phoneNumbers->data); + weight += getWeight(number, filter); + phoneNumbers = phoneNumbers->next; + } + + // SIPURI + if (linphone_address_get_username(lAddress) != nullptr) { + weight += getWeight(linphone_address_get_username(lAddress), filter); + } + + // DISPLAYNAME + if (linphone_address_get_display_name(lAddress) != nullptr) { + weight += getWeight(linphone_address_get_display_name(lAddress), filter); + } + + return SearchResult(weight, lAddress, lFriend); +} + unsigned int MagicSearch::getWeight(const string &stringWords, const string &filter) const { size_t weight = string::npos; // Finding all occurrences of "filter" in "stringWords" - for (size_t w = stringWords.find(filter) ; w != string::npos ; w = stringWords.find(filter, w)) { + for (size_t w = stringWords.find(filter); + w != string::npos; + w = stringWords.find(filter, w + filter.length()) + ) { // weight max if occurence find at beginning if (w == 0) { weight = getMaxWeight(); } else { bool isDelimiter = false; - // get the char before the matched filter - const char l = stringWords.at(w - 1); - // Check if it's a delimiter - for (const char d : getDelimiter()) { - if (l == d) { - isDelimiter = true; - break; + if (getUseDelimiter()) { + // get the char before the matched filter + const char l = stringWords.at(w - 1); + // Check if it's a delimiter + for (const char d : getDelimiter()) { + if (l == d) { + isDelimiter = true; + break; + } } } unsigned int newWeight = getMaxWeight() - (unsigned int)((isDelimiter) ? 1 : w + 1); weight = (weight != string::npos) ? weight + newWeight : newWeight; } + // Only one search on the stringWords for the moment + // due to weight calcul which dos not take into the case of multiple occurence + break; } return (weight != string::npos) ? (unsigned int)(weight) : getMinWeight(); } -MagicSearch::~MagicSearch() {} - LINPHONE_END_NAMESPACE diff --git a/src/search/magic-search.h b/src/search/magic-search.h index 5b6caa262..c3f901ffc 100644 --- a/src/search/magic-search.h +++ b/src/search/magic-search.h @@ -36,6 +36,7 @@ class LINPHONE_PUBLIC MagicSearch : public CoreAccessor, public Object{ public: MagicSearch(const std::shared_ptr &core); + MagicSearch(const MagicSearch &ms) = delete; ~MagicSearch(); /** @@ -71,6 +72,17 @@ public: **/ void setDelimiter(const std::string &delimiter); + /** + * @return if the delimiter search is used + **/ + bool getUseDelimiter() const; + + /** + * Enable or disable the delimiter in search + * @param[in] enable + **/ + void setUseDelimiter(bool enable); + /** * @return the number of the maximum SearchResult which will be return **/ @@ -93,21 +105,68 @@ public: **/ void setLimitedSearch(const bool limited); + /** + * Reset the cache to begin a new search + **/ + void resetSearchCache(); + /** * Create a sorted list of SearchResult from SipUri, Contact name, * Contact displayname, Contact phone number, which match with a filter word + * During the first search, a cache is created and used for the next search and so on + * Use resetSearchCache() to begin a new search * @param[in] filter word we search * @param[in] withDomain domain which we want to search only - * @return sorted list of SearchResult with "filter" + * @return sorted list of SearchResult with "filter" or an empty list if "filter" is empty **/ - std::list getContactListFromFilter(const std::string &filter, const std::string &withDomain = "") const; + std::list getContactListFromFilter(const std::string &filter, const std::string &withDomain = ""); private: + + /** + * @return the cache of precedent result + * @private + **/ + std::list *getSearchCache() const; + + /** + * Save a result for future search + * @param[in] cache result we want to save + * @private + **/ + void setSearchCache(std::list *cache); + + /** + * Begin the search from friend list + * @param[in] filter word we search + * @param[in] withDomain domain which we want to search only + * @private + **/ + std::list *beginNewSearch(const std::string &filter, const std::string &withDomain); + + /** + * Continue the search from the cache of precedent search + * @param[in] filter word we search + * @param[in] withDomain domain which we want to search only + * @private + **/ + std::list *continueSearch(const std::string &filter, const std::string &withDomain); + + /** + * Continue the search from the cache of precedent search + * @param[in] lFriend friend whose informations will be check + * @param[in] filter word we search + * @param[in] withDomain domain which we want to search only + * @private + **/ + SearchResult search(const LinphoneFriend* lFriend, const std::string &filter, const std::string &withDomain); + /** * Return a weight for a searched in with a filter * @param[in] stringWords which where we are searching * @param[in] filter what we are searching * @return calculate weight + * @private **/ unsigned int getWeight(const std::string &stringWords, const std::string &filter) const; diff --git a/src/search/search-result.cpp b/src/search/search-result.cpp index d60cd4a2b..2c032e76b 100644 --- a/src/search/search-result.cpp +++ b/src/search/search-result.cpp @@ -40,11 +40,19 @@ SearchResult::SearchResult(const SearchResult &sr) : ClonableObject(*new SearchR SearchResult::~SearchResult() {}; -bool SearchResult::operator<(const SearchResult& rsr) { +bool SearchResult::operator<(const SearchResult& rsr) const{ return this->getWeight() < rsr.getWeight(); } -bool SearchResult::operator=(const SearchResult& rsr) { +bool SearchResult::operator>(const SearchResult& rsr) const{ + return this->getWeight() > rsr.getWeight(); +} + +bool SearchResult::operator>=(const SearchResult& rsr) const{ + return this->getWeight() >= rsr.getWeight(); +} + +bool SearchResult::operator=(const SearchResult& rsr) const{ return this->getWeight() == rsr.getWeight(); } diff --git a/src/search/search-result.h b/src/search/search-result.h index 8c5b87522..d453a273a 100644 --- a/src/search/search-result.h +++ b/src/search/search-result.h @@ -36,8 +36,10 @@ public: SearchResult(const SearchResult &sr); ~SearchResult(); - bool operator<(const SearchResult& rsr); - bool operator=(const SearchResult& rsr); + bool operator<(const SearchResult& rsr) const; + bool operator>(const SearchResult& rsr) const; + bool operator>=(const SearchResult& rsr) const; + bool operator=(const SearchResult& rsr) const; /** * @return LinphoneFriend associed diff --git a/tester/setup_tester.c b/tester/setup_tester.c index 202aaab1a..bb95bd70b 100644 --- a/tester/setup_tester.c +++ b/tester/setup_tester.c @@ -17,27 +17,56 @@ */ -#include "linphone/core.h" #include "liblinphone_tester.h" -#include "tester_utils.h" +#include "linphone/core.h" +#include "linphone/friend.h" +#include "linphone/friendlist.h" #include "linphone/lpconfig.h" +#include "linphone/api/c-magic-search.h" #include "tester_utils.h" -static const char *sFriends[5] = { +#define S_SIZE_FRIEND 10 +static const unsigned int sSizeFriend = S_SIZE_FRIEND; +static const char *sFriends[S_SIZE_FRIEND] = { "sip:test@sip.example.org", "sip:test2@sip.example.org", "sip:allo@sip.example.org", "sip:hello@sip.example.org", - "sip:hello@sip.test.org" + "sip:hello@sip.test.org", + "sip:marie@sip.example.org", + "sip:laura@sip.example.org", + "sip:loic@sip.example.org", + "sip:laure@sip.test.org", + "sip:loic@sip.test.org" }; -static void _create_friend_from_tab(LinphoneCore *lc, LinphoneFriendList *list, const char *friends[], const unsigned int size) { - for (unsigned int i = 0 ; i <= size ; i++) { +static void _create_friends_from_tab(LinphoneCore *lc, LinphoneFriendList *list, const char *friends[], const unsigned int size) { + for (unsigned int i = 0 ; i < size ; i++) { LinphoneFriend *fr = linphone_core_create_friend_with_address(lc, friends[i]); linphone_friend_list_add_friend(list, fr); } } +static void _remove_friends_from_list(LinphoneFriendList *list, const char *friends[], const unsigned int size) { + for (unsigned int i = 0 ; i < size ; i++) { + LinphoneFriend *fr = linphone_friend_list_find_friend_by_uri(list, friends[i]); + if (fr != NULL) linphone_friend_list_remove_friend(list, fr); + } +} + +static void _check_friend_result_list(const bctbx_list_t *resultList, const unsigned int index, const char* uri) { + const LinphoneSearchResult *sr = bctbx_list_nth_data(resultList, index); + const LinphoneFriend *lf = linphone_search_result_get_friend(sr); + BC_ASSERT_PTR_NOT_NULL(lf); + if (lf != NULL) { + const LinphoneAddress *la = linphone_friend_get_address(lf); + BC_ASSERT_PTR_NOT_NULL(la); + if (la != NULL) { + BC_ASSERT_STRING_EQUAL(linphone_address_as_string(la) , uri); + } + } +} + static void linphone_version_test(void){ const char *version=linphone_core_get_version(); /*make sure the git version is always included in the version number*/ @@ -409,13 +438,101 @@ static void custom_tones_setup(void){ } static void search_friend_all_domains(void) { + LinphoneMagicSearch *magicSearch = NULL; + bctbx_list_t *resultList = NULL; LinphoneCoreManager* manager = linphone_core_manager_new2("empty_rc", FALSE); LinphoneFriendList *lfl = linphone_core_get_default_friend_list(manager->lc); - LinphoneFriend *lf = linphone_core_create_friend_with_address(manager->lc, "sip:toto@sip.linphone.org"); - _create_friend_from_tab(manager->lc, lfl, sFriends, 5); + _create_friends_from_tab(manager->lc, lfl, sFriends, sSizeFriend); + + magicSearch = linphone_magic_search_new(manager->lc); + + resultList = linphone_magic_search_get_contact_list_from_filter(magicSearch, "llo", ""); + + BC_ASSERT_PTR_NOT_NULL(resultList); + + if (resultList != NULL) { + BC_ASSERT_EQUAL(bctbx_list_size(resultList), 3, int, "%d"); + _check_friend_result_list(resultList, 0, sFriends[2]);//"sip:allo@sip.example.org" + _check_friend_result_list(resultList, 1, sFriends[3]);//"sip:hello@sip.example.org" + _check_friend_result_list(resultList, 2, sFriends[4]);//"sip:hello@sip.test.org" + } + + free(resultList); + + _remove_friends_from_list(lfl, sFriends, sSizeFriend); + + linphone_core_manager_destroy(manager); +} + +static void search_friend_one_domain(void) { + LinphoneMagicSearch *magicSearch = NULL; + bctbx_list_t *resultList = NULL; + LinphoneCoreManager* manager = linphone_core_manager_new2("empty_rc", FALSE); + LinphoneFriendList *lfl = linphone_core_get_default_friend_list(manager->lc); + + _create_friends_from_tab(manager->lc, lfl, sFriends, sSizeFriend); + + magicSearch = linphone_magic_search_new(manager->lc); + + resultList = linphone_magic_search_get_contact_list_from_filter(magicSearch, "llo", "sip.example.org"); + + BC_ASSERT_PTR_NOT_NULL(resultList); + + if (resultList != NULL) { + BC_ASSERT_EQUAL(bctbx_list_size(resultList), 2, int, "%d"); + _check_friend_result_list(resultList, 0, sFriends[2]);//"sip:allo@sip.example.org" + _check_friend_result_list(resultList, 1, sFriends[3]);//"sip:hello@sip.example.org" + } + + free(resultList); + + _remove_friends_from_list(lfl, sFriends, sSizeFriend); + + linphone_core_manager_destroy(manager); +} + +static void search_friend_research_estate(void) { + LinphoneMagicSearch *magicSearch = NULL; + bctbx_list_t *resultList = NULL; + LinphoneCoreManager* manager = linphone_core_manager_new2("empty_rc", FALSE); + LinphoneFriendList *lfl = linphone_core_get_default_friend_list(manager->lc); + + _create_friends_from_tab(manager->lc, lfl, sFriends, sSizeFriend); + + magicSearch = linphone_magic_search_new(manager->lc); + + resultList = linphone_magic_search_get_contact_list_from_filter(magicSearch, "l", ""); + + BC_ASSERT_PTR_NOT_NULL(resultList); + + if (resultList != NULL) { + BC_ASSERT_EQUAL(bctbx_list_size(resultList), 7, int, "%d"); + _check_friend_result_list(resultList, 0, sFriends[6]);//"sip:laura@sip.example.org" + _check_friend_result_list(resultList, 1, sFriends[7]);//"sip:loic@sip.example.org" + _check_friend_result_list(resultList, 2, sFriends[8]);//"sip:laure@sip.test.org" + _check_friend_result_list(resultList, 3, sFriends[9]);//"sip:loic@sip.test.org" + _check_friend_result_list(resultList, 4, sFriends[2]);//"sip:allo@sip.example.org" + _check_friend_result_list(resultList, 5, sFriends[3]);//"sip:hello@sip.example.org" + _check_friend_result_list(resultList, 6, sFriends[4]);//"sip:hello@sip.test.org" + } + + free(resultList); + + resultList = linphone_magic_search_get_contact_list_from_filter(magicSearch, "la", ""); + + BC_ASSERT_PTR_NOT_NULL(resultList); + + if (resultList != NULL) { + BC_ASSERT_EQUAL(bctbx_list_size(resultList), 2, int, "%d"); + _check_friend_result_list(resultList, 0, sFriends[8]);//"sip:laure@sip.test.org" + _check_friend_result_list(resultList, 1, sFriends[6]);//"sip:laura@sip.example.org" + } + + free(resultList); + + _remove_friends_from_list(lfl, sFriends, sSizeFriend); - linphone_friend_unref(lf); linphone_core_manager_destroy(manager); } @@ -436,7 +553,9 @@ test_t setup_tests[] = { TEST_NO_TAG("Codec usability", codec_usability_test), TEST_NO_TAG("Codec setup", codec_setup), TEST_NO_TAG("Custom tones setup", custom_tones_setup), - TEST_NO_TAG("Search friend from all domains", search_friend_all_domains) + TEST_TWO_TAGS("Search friend from all domains", search_friend_all_domains, "MagicSearch", "LeaksMemory"), + TEST_TWO_TAGS("Search friend from one domain", search_friend_one_domain, "MagicSearch", "LeaksMemory"), + TEST_TWO_TAGS("Multiple looking for friends", search_friend_research_estate, "MagicSearch", "LeaksMemory") }; test_suite_t setup_test_suite = {"Setup", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each,