diff --git a/CHANGELOG.md b/CHANGELOG.md index b9d66551e..9bf3ea7dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,20 @@ # Changelog for the Mapbox Search SDK for Android +## 2.7.0-rc.1 + +### New features +- Added new function to search for multiple categories, e.g., `SearchEngine.search(listOf("coffee_shop", "hotel"), ...)`, +- New option `CategorySearchOptions.ensureResultsPerCategory` is available. It allows to request category search results to include at least one POI for each category, provided a POI is available in a nearby location. + +### Bug fixes +- Fixed photos metadata parsing for the `ApiType.SEARCH_BOX`. + +### Mapbox dependencies +- Search Native SDK `2.7.0-rc.1` +- Common SDK `24.9.0-rc.1` + + + ## 2.7.0-beta.1 ### New features diff --git a/MapboxSearch/base/src/main/java/com/mapbox/search/base/core/CoreFactoryFunctions.kt b/MapboxSearch/base/src/main/java/com/mapbox/search/base/core/CoreFactoryFunctions.kt index b3396ebf8..26bc08022 100644 --- a/MapboxSearch/base/src/main/java/com/mapbox/search/base/core/CoreFactoryFunctions.kt +++ b/MapboxSearch/base/src/main/java/com/mapbox/search/base/core/CoreFactoryFunctions.kt @@ -26,6 +26,7 @@ fun createCoreSearchOptions( timeDeviation: Double? = null, addonAPI: Map? = null, offlineSearchPlacesOutsideBbox: Boolean = false, + ensureResultsPerCategory: Boolean? = null, ): CoreSearchOptions = CoreSearchOptions( proximity = proximity, origin = origin, @@ -45,6 +46,7 @@ fun createCoreSearchOptions( timeDeviation = timeDeviation, addonAPI = addonAPI?.let { it as? HashMap ?: HashMap(it) }, offlineSearchPlacesOutsideBbox = offlineSearchPlacesOutsideBbox, + ensureResultsPerCategory = ensureResultsPerCategory, ) fun createCoreReverseGeoOptions( diff --git a/MapboxSearch/common-tests/src/main/java/com/mapbox/search/common/tests/CoreTestDataFactory.kt b/MapboxSearch/common-tests/src/main/java/com/mapbox/search/common/tests/CoreTestDataFactory.kt index 595f570c7..5f9239367 100644 --- a/MapboxSearch/common-tests/src/main/java/com/mapbox/search/common/tests/CoreTestDataFactory.kt +++ b/MapboxSearch/common-tests/src/main/java/com/mapbox/search/common/tests/CoreTestDataFactory.kt @@ -48,6 +48,7 @@ fun createTestCoreSearchOptions( timeDeviation: Double? = null, addonAPI: Map? = null, offlineSearchPlacesOutsideBbox: Boolean = false, + ensureResultsPerCategory: Boolean? = null, ): SearchOptions = SearchOptions( proximity, origin, @@ -67,6 +68,7 @@ fun createTestCoreSearchOptions( timeDeviation, addonAPI?.let { it as? HashMap ?: HashMap(it) }, offlineSearchPlacesOutsideBbox, + ensureResultsPerCategory, ) @Suppress("LongParameterList") diff --git a/MapboxSearch/gradle.properties b/MapboxSearch/gradle.properties index 4c18dcb79..665e145ab 100644 --- a/MapboxSearch/gradle.properties +++ b/MapboxSearch/gradle.properties @@ -21,7 +21,7 @@ android.enableJetifier=false kotlin.code.style=official # SDK version attributes -VERSION_NAME=2.7.0-beta.1 +VERSION_NAME=2.7.0-rc.1 # Artifact attributes mapboxArtifactUserOrg=mapbox diff --git a/MapboxSearch/gradle/versions.gradle b/MapboxSearch/gradle/versions.gradle index 35ae9a4a8..1396db872 100644 --- a/MapboxSearch/gradle/versions.gradle +++ b/MapboxSearch/gradle/versions.gradle @@ -44,10 +44,10 @@ ext { mapbox_maps_version = '11.9.0-beta.1' mapbox_turf_version = '6.15.0' - common_sdk_version = '24.9.0-beta.1' + common_sdk_version = '24.9.0-rc.1' mapbox_base_version = '0.8.0' - search_native_version = '2.7.0-beta.1' + search_native_version = '2.7.0-rc.1' detekt_version = '1.19.0' diff --git a/MapboxSearch/sample/src/main/java/com/mapbox/search/sample/api/CategorySearchJavaExampleActivity.java b/MapboxSearch/sample/src/main/java/com/mapbox/search/sample/api/CategorySearchJavaExampleActivity.java index 3a697d67f..190555eea 100644 --- a/MapboxSearch/sample/src/main/java/com/mapbox/search/sample/api/CategorySearchJavaExampleActivity.java +++ b/MapboxSearch/sample/src/main/java/com/mapbox/search/sample/api/CategorySearchJavaExampleActivity.java @@ -15,9 +15,8 @@ import com.mapbox.search.SearchEngineSettings; import com.mapbox.search.common.AsyncOperationTask; import com.mapbox.search.result.SearchResult; -import com.mapbox.search.sample.BuildConfig; -import com.mapbox.search.sample.R; +import java.util.Arrays; import java.util.List; public class CategorySearchJavaExampleActivity extends AppCompatActivity { @@ -51,10 +50,15 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { ); final CategorySearchOptions options = new CategorySearchOptions.Builder() - .limit(1) + .limit(10) + .ensureResultsPerCategory(true) .build(); - searchRequestTask = searchEngine.search("cafe", options, searchCallback); + searchRequestTask = searchEngine.search( + Arrays.asList("cafe", "coffee_shop", "hotel"), + options, + searchCallback + ); } @Override diff --git a/MapboxSearch/sample/src/main/java/com/mapbox/search/sample/api/CategorySearchKotlinExampleActivity.kt b/MapboxSearch/sample/src/main/java/com/mapbox/search/sample/api/CategorySearchKotlinExampleActivity.kt index ef3dc076e..782e5fd02 100644 --- a/MapboxSearch/sample/src/main/java/com/mapbox/search/sample/api/CategorySearchKotlinExampleActivity.kt +++ b/MapboxSearch/sample/src/main/java/com/mapbox/search/sample/api/CategorySearchKotlinExampleActivity.kt @@ -48,8 +48,11 @@ class CategorySearchKotlinExampleActivity : BaseKotlinExampleActivity() { override fun startExample() { searchRequestTask = searchEngine.search( - "cafe", - CategorySearchOptions(limit = 1), + listOf("cafe", "coffee_shop", "hotel"), + CategorySearchOptions( + limit = 10, + ensureResultsPerCategory = true, + ), searchCallback ) } diff --git a/MapboxSearch/sdk/api/api-metalava.txt b/MapboxSearch/sdk/api/api-metalava.txt index bb9098c3d..3b9fcd08c 100644 --- a/MapboxSearch/sdk/api/api-metalava.txt +++ b/MapboxSearch/sdk/api/api-metalava.txt @@ -21,6 +21,7 @@ package com.mapbox.search { } @kotlinx.parcelize.Parcelize public final class CategorySearchOptions implements android.os.Parcelable { + ctor public CategorySearchOptions(com.mapbox.geojson.Point? proximity = null, com.mapbox.geojson.BoundingBox? boundingBox = null, java.util.List? countries = null, Boolean? fuzzyMatch = null, java.util.List? languages = defaultSearchOptionsLanguage(), Integer? limit = null, Integer? requestDebounce = null, com.mapbox.geojson.Point? origin = null, com.mapbox.search.common.NavigationProfile? navigationProfile = null, com.mapbox.search.RouteOptions? routeOptions = null, java.util.Map? unsafeParameters = null, boolean ignoreIndexableRecords = false, Double? indexableRecordsDistanceThresholdMeters = null, Boolean? ensureResultsPerCategory = null); ctor public CategorySearchOptions(com.mapbox.geojson.Point? proximity = null, com.mapbox.geojson.BoundingBox? boundingBox = null, java.util.List? countries = null, Boolean? fuzzyMatch = null, java.util.List? languages = defaultSearchOptionsLanguage(), Integer? limit = null, Integer? requestDebounce = null, com.mapbox.geojson.Point? origin = null, com.mapbox.search.common.NavigationProfile? navigationProfile = null, com.mapbox.search.RouteOptions? routeOptions = null, java.util.Map? unsafeParameters = null, boolean ignoreIndexableRecords = false, Double? indexableRecordsDistanceThresholdMeters = null); ctor public CategorySearchOptions(com.mapbox.geojson.Point? proximity = null, com.mapbox.geojson.BoundingBox? boundingBox = null, java.util.List? countries = null, Boolean? fuzzyMatch = null, java.util.List? languages = defaultSearchOptionsLanguage(), Integer? limit = null, Integer? requestDebounce = null, com.mapbox.geojson.Point? origin = null, com.mapbox.search.common.NavigationProfile? navigationProfile = null, com.mapbox.search.RouteOptions? routeOptions = null, java.util.Map? unsafeParameters = null, boolean ignoreIndexableRecords = false); ctor public CategorySearchOptions(com.mapbox.geojson.Point? proximity = null, com.mapbox.geojson.BoundingBox? boundingBox = null, java.util.List? countries = null, Boolean? fuzzyMatch = null, java.util.List? languages = defaultSearchOptionsLanguage(), Integer? limit = null, Integer? requestDebounce = null, com.mapbox.geojson.Point? origin = null, com.mapbox.search.common.NavigationProfile? navigationProfile = null, com.mapbox.search.RouteOptions? routeOptions = null, java.util.Map? unsafeParameters = null); @@ -36,6 +37,7 @@ package com.mapbox.search { ctor public CategorySearchOptions(com.mapbox.geojson.Point? proximity = null); method public com.mapbox.geojson.BoundingBox? getBoundingBox(); method public java.util.List? getCountries(); + method public Boolean? getEnsureResultsPerCategory(); method public Boolean? getFuzzyMatch(); method public boolean getIgnoreIndexableRecords(); method public Double? getIndexableRecordsDistanceThresholdMeters(); @@ -50,6 +52,7 @@ package com.mapbox.search { method public com.mapbox.search.CategorySearchOptions.Builder toBuilder(); property public final com.mapbox.geojson.BoundingBox? boundingBox; property public final java.util.List? countries; + property public final Boolean? ensureResultsPerCategory; property public final Boolean? fuzzyMatch; property public final boolean ignoreIndexableRecords; property public final Double? indexableRecordsDistanceThresholdMeters; @@ -69,6 +72,7 @@ package com.mapbox.search { method public com.mapbox.search.CategorySearchOptions build(); method public com.mapbox.search.CategorySearchOptions.Builder countries(com.mapbox.search.common.IsoCountryCode... countries); method public com.mapbox.search.CategorySearchOptions.Builder countries(java.util.List countries); + method public com.mapbox.search.CategorySearchOptions.Builder ensureResultsPerCategory(Boolean? ensureResultsPerCategory); method public com.mapbox.search.CategorySearchOptions.Builder fuzzyMatch(boolean fuzzyMatch); method public com.mapbox.search.CategorySearchOptions.Builder ignoreIndexableRecords(boolean ignoreIndexableRecords); method public com.mapbox.search.CategorySearchOptions.Builder indexableRecordsDistanceThresholdMeters(Double? threshold); @@ -291,8 +295,10 @@ package com.mapbox.search { method public default com.mapbox.search.common.AsyncOperationTask retrieve(String mapboxId, com.mapbox.search.SearchResultCallback callback); method public com.mapbox.search.common.AsyncOperationTask search(String query, com.mapbox.search.SearchOptions options, java.util.concurrent.Executor executor, com.mapbox.search.SearchSuggestionsCallback callback); method public default com.mapbox.search.common.AsyncOperationTask search(String query, com.mapbox.search.SearchOptions options, com.mapbox.search.SearchSuggestionsCallback callback); - method public com.mapbox.search.common.AsyncOperationTask search(String categoryName, com.mapbox.search.CategorySearchOptions options, java.util.concurrent.Executor executor, com.mapbox.search.SearchCallback callback); + method public default com.mapbox.search.common.AsyncOperationTask search(String categoryName, com.mapbox.search.CategorySearchOptions options, java.util.concurrent.Executor executor, com.mapbox.search.SearchCallback callback); method public default com.mapbox.search.common.AsyncOperationTask search(String categoryName, com.mapbox.search.CategorySearchOptions options, com.mapbox.search.SearchCallback callback); + method public com.mapbox.search.common.AsyncOperationTask search(java.util.List categoryNames, com.mapbox.search.CategorySearchOptions options, java.util.concurrent.Executor executor, com.mapbox.search.SearchCallback callback); + method public default com.mapbox.search.common.AsyncOperationTask search(java.util.List categoryNames, com.mapbox.search.CategorySearchOptions options, com.mapbox.search.SearchCallback callback); method public com.mapbox.search.common.AsyncOperationTask search(com.mapbox.search.ReverseGeoOptions options, java.util.concurrent.Executor executor, com.mapbox.search.SearchCallback callback); method public default com.mapbox.search.common.AsyncOperationTask search(com.mapbox.search.ReverseGeoOptions options, com.mapbox.search.SearchCallback callback); method public default com.mapbox.search.common.AsyncOperationTask select(com.mapbox.search.result.SearchSuggestion suggestion, com.mapbox.search.SearchSelectionCallback callback); diff --git a/MapboxSearch/sdk/api/sdk.api b/MapboxSearch/sdk/api/sdk.api index 10de4b084..3b451ed83 100644 --- a/MapboxSearch/sdk/api/sdk.api +++ b/MapboxSearch/sdk/api/sdk.api @@ -38,13 +38,15 @@ public final class com/mapbox/search/CategorySearchOptions : android/os/Parcelab public fun (Lcom/mapbox/geojson/Point;Lcom/mapbox/geojson/BoundingBox;Ljava/util/List;Ljava/lang/Boolean;Ljava/util/List;Ljava/lang/Integer;Ljava/lang/Integer;Lcom/mapbox/geojson/Point;Lcom/mapbox/search/common/NavigationProfile;Lcom/mapbox/search/RouteOptions;Ljava/util/Map;)V public fun (Lcom/mapbox/geojson/Point;Lcom/mapbox/geojson/BoundingBox;Ljava/util/List;Ljava/lang/Boolean;Ljava/util/List;Ljava/lang/Integer;Ljava/lang/Integer;Lcom/mapbox/geojson/Point;Lcom/mapbox/search/common/NavigationProfile;Lcom/mapbox/search/RouteOptions;Ljava/util/Map;Z)V public fun (Lcom/mapbox/geojson/Point;Lcom/mapbox/geojson/BoundingBox;Ljava/util/List;Ljava/lang/Boolean;Ljava/util/List;Ljava/lang/Integer;Ljava/lang/Integer;Lcom/mapbox/geojson/Point;Lcom/mapbox/search/common/NavigationProfile;Lcom/mapbox/search/RouteOptions;Ljava/util/Map;ZLjava/lang/Double;)V - public synthetic fun (Lcom/mapbox/geojson/Point;Lcom/mapbox/geojson/BoundingBox;Ljava/util/List;Ljava/lang/Boolean;Ljava/util/List;Ljava/lang/Integer;Ljava/lang/Integer;Lcom/mapbox/geojson/Point;Lcom/mapbox/search/common/NavigationProfile;Lcom/mapbox/search/RouteOptions;Ljava/util/Map;ZLjava/lang/Double;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public final synthetic fun copy (Lcom/mapbox/geojson/Point;Lcom/mapbox/geojson/BoundingBox;Ljava/util/List;Ljava/lang/Boolean;Ljava/util/List;Ljava/lang/Integer;Ljava/lang/Integer;Lcom/mapbox/geojson/Point;Lcom/mapbox/search/common/NavigationProfile;Lcom/mapbox/search/RouteOptions;Ljava/util/Map;ZLjava/lang/Double;)Lcom/mapbox/search/CategorySearchOptions; - public static synthetic fun copy$default (Lcom/mapbox/search/CategorySearchOptions;Lcom/mapbox/geojson/Point;Lcom/mapbox/geojson/BoundingBox;Ljava/util/List;Ljava/lang/Boolean;Ljava/util/List;Ljava/lang/Integer;Ljava/lang/Integer;Lcom/mapbox/geojson/Point;Lcom/mapbox/search/common/NavigationProfile;Lcom/mapbox/search/RouteOptions;Ljava/util/Map;ZLjava/lang/Double;ILjava/lang/Object;)Lcom/mapbox/search/CategorySearchOptions; + public fun (Lcom/mapbox/geojson/Point;Lcom/mapbox/geojson/BoundingBox;Ljava/util/List;Ljava/lang/Boolean;Ljava/util/List;Ljava/lang/Integer;Ljava/lang/Integer;Lcom/mapbox/geojson/Point;Lcom/mapbox/search/common/NavigationProfile;Lcom/mapbox/search/RouteOptions;Ljava/util/Map;ZLjava/lang/Double;Ljava/lang/Boolean;)V + public synthetic fun (Lcom/mapbox/geojson/Point;Lcom/mapbox/geojson/BoundingBox;Ljava/util/List;Ljava/lang/Boolean;Ljava/util/List;Ljava/lang/Integer;Ljava/lang/Integer;Lcom/mapbox/geojson/Point;Lcom/mapbox/search/common/NavigationProfile;Lcom/mapbox/search/RouteOptions;Ljava/util/Map;ZLjava/lang/Double;Ljava/lang/Boolean;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final synthetic fun copy (Lcom/mapbox/geojson/Point;Lcom/mapbox/geojson/BoundingBox;Ljava/util/List;Ljava/lang/Boolean;Ljava/util/List;Ljava/lang/Integer;Ljava/lang/Integer;Lcom/mapbox/geojson/Point;Lcom/mapbox/search/common/NavigationProfile;Lcom/mapbox/search/RouteOptions;Ljava/util/Map;ZLjava/lang/Double;Ljava/lang/Boolean;)Lcom/mapbox/search/CategorySearchOptions; + public static synthetic fun copy$default (Lcom/mapbox/search/CategorySearchOptions;Lcom/mapbox/geojson/Point;Lcom/mapbox/geojson/BoundingBox;Ljava/util/List;Ljava/lang/Boolean;Ljava/util/List;Ljava/lang/Integer;Ljava/lang/Integer;Lcom/mapbox/geojson/Point;Lcom/mapbox/search/common/NavigationProfile;Lcom/mapbox/search/RouteOptions;Ljava/util/Map;ZLjava/lang/Double;Ljava/lang/Boolean;ILjava/lang/Object;)Lcom/mapbox/search/CategorySearchOptions; public fun describeContents ()I public fun equals (Ljava/lang/Object;)Z public final fun getBoundingBox ()Lcom/mapbox/geojson/BoundingBox; public final fun getCountries ()Ljava/util/List; + public final fun getEnsureResultsPerCategory ()Ljava/lang/Boolean; public final fun getFuzzyMatch ()Ljava/lang/Boolean; public final fun getIgnoreIndexableRecords ()Z public final fun getIndexableRecordsDistanceThresholdMeters ()Ljava/lang/Double; @@ -68,6 +70,7 @@ public final class com/mapbox/search/CategorySearchOptions$Builder { public final fun build ()Lcom/mapbox/search/CategorySearchOptions; public final fun countries (Ljava/util/List;)Lcom/mapbox/search/CategorySearchOptions$Builder; public final fun countries ([Lcom/mapbox/search/common/IsoCountryCode;)Lcom/mapbox/search/CategorySearchOptions$Builder; + public final fun ensureResultsPerCategory (Ljava/lang/Boolean;)Lcom/mapbox/search/CategorySearchOptions$Builder; public final fun fuzzyMatch (Z)Lcom/mapbox/search/CategorySearchOptions$Builder; public final fun ignoreIndexableRecords (Z)Lcom/mapbox/search/CategorySearchOptions$Builder; public final fun indexableRecordsDistanceThresholdMeters (Ljava/lang/Double;)Lcom/mapbox/search/CategorySearchOptions$Builder; @@ -375,6 +378,8 @@ public abstract interface class com/mapbox/search/SearchEngine { public abstract fun search (Ljava/lang/String;Lcom/mapbox/search/CategorySearchOptions;Ljava/util/concurrent/Executor;Lcom/mapbox/search/SearchCallback;)Lcom/mapbox/search/common/AsyncOperationTask; public abstract fun search (Ljava/lang/String;Lcom/mapbox/search/SearchOptions;Lcom/mapbox/search/SearchSuggestionsCallback;)Lcom/mapbox/search/common/AsyncOperationTask; public abstract fun search (Ljava/lang/String;Lcom/mapbox/search/SearchOptions;Ljava/util/concurrent/Executor;Lcom/mapbox/search/SearchSuggestionsCallback;)Lcom/mapbox/search/common/AsyncOperationTask; + public abstract fun search (Ljava/util/List;Lcom/mapbox/search/CategorySearchOptions;Lcom/mapbox/search/SearchCallback;)Lcom/mapbox/search/common/AsyncOperationTask; + public abstract fun search (Ljava/util/List;Lcom/mapbox/search/CategorySearchOptions;Ljava/util/concurrent/Executor;Lcom/mapbox/search/SearchCallback;)Lcom/mapbox/search/common/AsyncOperationTask; public abstract fun select (Lcom/mapbox/search/result/SearchSuggestion;Lcom/mapbox/search/SearchSelectionCallback;)Lcom/mapbox/search/common/AsyncOperationTask; public abstract fun select (Lcom/mapbox/search/result/SearchSuggestion;Lcom/mapbox/search/SelectOptions;Lcom/mapbox/search/SearchSelectionCallback;)Lcom/mapbox/search/common/AsyncOperationTask; public abstract fun select (Lcom/mapbox/search/result/SearchSuggestion;Lcom/mapbox/search/SelectOptions;Ljava/util/concurrent/Executor;Lcom/mapbox/search/SearchSelectionCallback;)Lcom/mapbox/search/common/AsyncOperationTask; @@ -403,7 +408,9 @@ public final class com/mapbox/search/SearchEngine$DefaultImpls { public static fun retrieve (Lcom/mapbox/search/SearchEngine;Ljava/lang/String;Lcom/mapbox/search/SearchResultCallback;)Lcom/mapbox/search/common/AsyncOperationTask; public static fun search (Lcom/mapbox/search/SearchEngine;Lcom/mapbox/search/ReverseGeoOptions;Lcom/mapbox/search/SearchCallback;)Lcom/mapbox/search/common/AsyncOperationTask; public static fun search (Lcom/mapbox/search/SearchEngine;Ljava/lang/String;Lcom/mapbox/search/CategorySearchOptions;Lcom/mapbox/search/SearchCallback;)Lcom/mapbox/search/common/AsyncOperationTask; + public static fun search (Lcom/mapbox/search/SearchEngine;Ljava/lang/String;Lcom/mapbox/search/CategorySearchOptions;Ljava/util/concurrent/Executor;Lcom/mapbox/search/SearchCallback;)Lcom/mapbox/search/common/AsyncOperationTask; public static fun search (Lcom/mapbox/search/SearchEngine;Ljava/lang/String;Lcom/mapbox/search/SearchOptions;Lcom/mapbox/search/SearchSuggestionsCallback;)Lcom/mapbox/search/common/AsyncOperationTask; + public static fun search (Lcom/mapbox/search/SearchEngine;Ljava/util/List;Lcom/mapbox/search/CategorySearchOptions;Lcom/mapbox/search/SearchCallback;)Lcom/mapbox/search/common/AsyncOperationTask; public static fun select (Lcom/mapbox/search/SearchEngine;Lcom/mapbox/search/result/SearchSuggestion;Lcom/mapbox/search/SearchSelectionCallback;)Lcom/mapbox/search/common/AsyncOperationTask; public static fun select (Lcom/mapbox/search/SearchEngine;Lcom/mapbox/search/result/SearchSuggestion;Lcom/mapbox/search/SelectOptions;Lcom/mapbox/search/SearchSelectionCallback;)Lcom/mapbox/search/common/AsyncOperationTask; public static fun select (Lcom/mapbox/search/SearchEngine;Ljava/util/List;Lcom/mapbox/search/SearchMultipleSelectionCallback;)Lcom/mapbox/search/common/AsyncOperationTask; diff --git a/MapboxSearch/sdk/src/androidTest/assets/search_box_responses/forward/retrieve-suggest.json b/MapboxSearch/sdk/src/androidTest/assets/search_box_responses/forward/retrieve-suggest.json index d7d33946f..94874abe7 100644 --- a/MapboxSearch/sdk/src/androidTest/assets/search_box_responses/forward/retrieve-suggest.json +++ b/MapboxSearch/sdk/src/androidTest/assets/search_box_responses/forward/retrieve-suggest.json @@ -74,14 +74,13 @@ "phone": "+123 456 789", "website": "https://www.test.com", "rating": 4.0, - "primary_photo":[ + "primary_photo": "https://test.com/img-primary.jpg", + "photos":[ { "width":300, "height":350, "url":"https://test.com/img-primary.jpg" - } - ], - "other_photo":[ + }, { "width":150, "height":350, diff --git a/MapboxSearch/sdk/src/androidTest/java/com/mapbox/search/details/DetailsApiIntegrationTest.kt b/MapboxSearch/sdk/src/androidTest/java/com/mapbox/search/details/DetailsApiIntegrationTest.kt index e25896118..5e62a750f 100644 --- a/MapboxSearch/sdk/src/androidTest/java/com/mapbox/search/details/DetailsApiIntegrationTest.kt +++ b/MapboxSearch/sdk/src/androidTest/java/com/mapbox/search/details/DetailsApiIntegrationTest.kt @@ -9,6 +9,7 @@ import com.mapbox.search.base.ExperimentalMapboxSearchAPI import com.mapbox.search.common.IsoCountryCode import com.mapbox.search.common.IsoLanguageCode import com.mapbox.search.common.SearchRequestException +import com.mapbox.search.common.metadata.ImageInfo import com.mapbox.search.common.metadata.OpenHours import com.mapbox.search.tests_support.BlockingSearchResultCallback import com.mapbox.search.utils.assertEqualsIgnoreCase @@ -91,7 +92,42 @@ internal class DetailsApiIntegrationTest : BaseTest() { assertEquals(Point.fromLngLat(-77.029129, 38.902309), searchResult.coordinate) assertTrue(searchResult.metadata?.openHours is OpenHours.Scheduled) assertEquals("+12029313139", searchResult.metadata?.phone) - assertEquals(5, searchResult.metadata?.otherPhotos?.size) + + assertEquals( + listOf( + ImageInfo( + url = "https://media-cdn.tripadvisor.com/media/photo-o/2a/08/ad/fe/caption.jpg", + width = 768, + height = 1024, + ), + ImageInfo( + url = "https://media-cdn.tripadvisor.com/media/photo-o/28/b6/2d/cc/caption.jpg", + width = 2006, + height = 975, + ), + ImageInfo( + url = "https://media-cdn.tripadvisor.com/media/photo-o/2a/45/ec/0a/caption.jpg", + width = 5184, + height = 3888, + ), + ImageInfo( + url = "https://media-cdn.tripadvisor.com/media/photo-o/28/b6/2d/ca/caption.jpg", + width = 2006, + height = 975, + ), + ), + searchResult.metadata?.otherPhotos + ) + assertEquals( + listOf( + ImageInfo( + url = "https://media-cdn.tripadvisor.com/media/photo-o/2a/08/ad/cd/caption.jpg", + width = 1024, + height = 768, + ), + ), + searchResult.metadata?.primaryPhotos + ) } @Test diff --git a/MapboxSearch/sdk/src/androidTest/java/com/mapbox/search/search_box/CategorySearchIntegrationTest.kt b/MapboxSearch/sdk/src/androidTest/java/com/mapbox/search/search_box/CategorySearchIntegrationTest.kt index a26b8e332..f667df430 100644 --- a/MapboxSearch/sdk/src/androidTest/java/com/mapbox/search/search_box/CategorySearchIntegrationTest.kt +++ b/MapboxSearch/sdk/src/androidTest/java/com/mapbox/search/search_box/CategorySearchIntegrationTest.kt @@ -120,7 +120,8 @@ internal class CategorySearchIntegrationTest : BaseTest() { limit = 5, origin = Point.fromLngLat(50.123, 70.123), navigationProfile = NavigationProfile.DRIVING, - routeOptions = TEST_ROUTE_OPTIONS + routeOptions = TEST_ROUTE_OPTIONS, + ensureResultsPerCategory = true, ) searchEngine.categorySearchBlocking(TEST_CATEGORY, options) @@ -148,9 +149,29 @@ internal class CategorySearchIntegrationTest : BaseTest() { assertFalse(url.queryParameter("route").isNullOrEmpty()) assertEquals("polyline6", url.queryParameter("route_geometry")) + assertEquals(options.ensureResultsPerCategory.toString(), url.queryParameter("ensure_results_per_category")) + assertFalse(request.headers["X-Request-ID"].isNullOrBlank()) } + @Test + fun testMultipleCategoriesSearchRequestParametersAreCorrect() { + mockServer.enqueue(MockResponse().setResponseCode(500)) + + val categories = listOf("cafe", "hotel") + searchEngine.categorySearchBlocking(categories, CategorySearchOptions()) + + val request = mockServer.takeRequest() + assertEqualsIgnoreCase("get", request.method!!) + + val url = request.requestUrl!! + assertEqualsIgnoreCase( + "//search/searchbox/v1/category/${categories.joinToString("%2c")}", + url.encodedPath, + ) + assertEquals(TEST_ACCESS_TOKEN, url.queryParameter("access_token")) + } + @Test fun testRequestDebounce() { mockServer.enqueue(MockResponse().setResponseCode(500)) diff --git a/MapboxSearch/sdk/src/androidTest/java/com/mapbox/search/search_box/ReverseGeocodingSearchIntegrationTest.kt b/MapboxSearch/sdk/src/androidTest/java/com/mapbox/search/search_box/ReverseGeocodingSearchIntegrationTest.kt index 8ee86122f..65d14f469 100644 --- a/MapboxSearch/sdk/src/androidTest/java/com/mapbox/search/search_box/ReverseGeocodingSearchIntegrationTest.kt +++ b/MapboxSearch/sdk/src/androidTest/java/com/mapbox/search/search_box/ReverseGeocodingSearchIntegrationTest.kt @@ -203,8 +203,8 @@ internal class ReverseGeocodingSearchIntegrationTest : BaseTest() { averageRating = 5.0, rating = 5.0f, description = "Famous symbol of France", - primaryPhotos = null, - otherPhotos = listOf(ImageInfo(url = "https://test.com/img1.jpg", width = 50, height = 50), ImageInfo(url = "https://test.com/img2.jpg", width = 150, height = 150)), + primaryPhotos = listOf(ImageInfo(url = "https://test.com/img1.jpg", width = 50, height = 50)), + otherPhotos = listOf(ImageInfo(url = "https://test.com/img2.jpg", width = 150, height = 150)), openHours = OpenHours.Scheduled( periods = listOf( OpenPeriod( diff --git a/MapboxSearch/sdk/src/androidTest/java/com/mapbox/search/tests_support/SearchEngine.kt b/MapboxSearch/sdk/src/androidTest/java/com/mapbox/search/tests_support/SearchEngine.kt index dbdceebe6..c5bcc5c9c 100644 --- a/MapboxSearch/sdk/src/androidTest/java/com/mapbox/search/tests_support/SearchEngine.kt +++ b/MapboxSearch/sdk/src/androidTest/java/com/mapbox/search/tests_support/SearchEngine.kt @@ -49,9 +49,17 @@ internal fun SearchEngine.categorySearchBlocking( categoryName: String, options: CategorySearchOptions = CategorySearchOptions(), executor: Executor = SearchSdkMainThreadWorker.mainExecutor, +): BlockingSearchCallback.SearchEngineResult { + return categorySearchBlocking(listOf(categoryName), options, executor) +} + +internal fun SearchEngine.categorySearchBlocking( + categories: List, + options: CategorySearchOptions = CategorySearchOptions(), + executor: Executor = SearchSdkMainThreadWorker.mainExecutor, ): BlockingSearchCallback.SearchEngineResult { val callback = BlockingSearchCallback() - search(categoryName, options, executor, callback) + search(categories, options, executor, callback) return callback.getResultBlocking() } diff --git a/MapboxSearch/sdk/src/main/java/com/mapbox/search/CategorySearchOptions.kt b/MapboxSearch/sdk/src/main/java/com/mapbox/search/CategorySearchOptions.kt index 7d3130338..43d0ad438 100644 --- a/MapboxSearch/sdk/src/main/java/com/mapbox/search/CategorySearchOptions.kt +++ b/MapboxSearch/sdk/src/main/java/com/mapbox/search/CategorySearchOptions.kt @@ -53,7 +53,8 @@ public class CategorySearchOptions @JvmOverloads public constructor( /** * Specify the maximum number of results to return, including results from [com.mapbox.search.record.IndexableDataProvider]. - * The maximum number of search results returned from the server is 10. + * The maximum number of search results is determined by server. For example, + * for the [ApiType.SEARCH_BOX] the maximum number of results to return is 25. */ public val limit: Int? = null, @@ -109,6 +110,28 @@ public class CategorySearchOptions @JvmOverloads public constructor( * Threshold specified in meters. */ public val indexableRecordsDistanceThresholdMeters: Double? = null, + + /** + * When set to true and multiple categories are requested, e.g. + * `SearchEngine.search(listOf("coffee_shop", "hotel"), ...)`, + * results will include at least one POI for each category, provided a POI is available + * in a nearby location. + * + * A comma-separated list of multiple category values in the request determines the sort order + * of the POI result. For example, for request + * `SearchEngine.search(listOf("coffee_shop", "hotel"), ...)`, coffee_shop POI will be listed + * first in the results. + * + * If there is more than one POI for categories, the number of search results will include + * multiple features for each category. For example, assuming that + * restaurant, coffee, parking_lot categories are requested and limit parameter is 10, + * the result will be ranked as follows: + * - 1st to 4th: restaurant POIs + * - 5th to 7th: coffee POIs + * - 8th to 10th: parking_lot POI + */ + @Reserved(SEARCH_BOX) + public val ensureResultsPerCategory: Boolean? = null, ) : Parcelable { init { @@ -135,7 +158,8 @@ public class CategorySearchOptions @JvmOverloads public constructor( routeOptions: RouteOptions? = this.routeOptions, unsafeParameters: Map? = this.unsafeParameters, ignoreIndexableRecords: Boolean = this.ignoreIndexableRecords, - indexableRecordsDistanceThresholdMeters: Double? = this.indexableRecordsDistanceThresholdMeters + indexableRecordsDistanceThresholdMeters: Double? = this.indexableRecordsDistanceThresholdMeters, + ensureResultsPerCategory: Boolean? = this.ensureResultsPerCategory, ): CategorySearchOptions { return CategorySearchOptions( proximity = proximity, @@ -151,6 +175,7 @@ public class CategorySearchOptions @JvmOverloads public constructor( unsafeParameters = unsafeParameters, ignoreIndexableRecords = ignoreIndexableRecords, indexableRecordsDistanceThresholdMeters = indexableRecordsDistanceThresholdMeters, + ensureResultsPerCategory = ensureResultsPerCategory, ) } @@ -183,6 +208,7 @@ public class CategorySearchOptions @JvmOverloads public constructor( if (unsafeParameters != other.unsafeParameters) return false if (ignoreIndexableRecords != other.ignoreIndexableRecords) return false if (!indexableRecordsDistanceThresholdMeters.safeCompareTo(other.indexableRecordsDistanceThresholdMeters)) return false + if (ensureResultsPerCategory != other.ensureResultsPerCategory) return false return true } @@ -204,6 +230,7 @@ public class CategorySearchOptions @JvmOverloads public constructor( result = 31 * result + (unsafeParameters?.hashCode() ?: 0) result = 31 * result + ignoreIndexableRecords.hashCode() result = 31 * result + indexableRecordsDistanceThresholdMeters.hashCode() + result = 31 * result + ensureResultsPerCategory.hashCode() return result } @@ -224,7 +251,8 @@ public class CategorySearchOptions @JvmOverloads public constructor( "routeOptions=$routeOptions, " + "unsafeParameters=$unsafeParameters, " + "ignoreIndexableRecords=$ignoreIndexableRecords, " + - "indexableRecordsDistanceThresholdMeters=$indexableRecordsDistanceThresholdMeters" + + "indexableRecordsDistanceThresholdMeters=$indexableRecordsDistanceThresholdMeters, " + + "ensureResultsPerCategory=$ensureResultsPerCategory" + ")" } @@ -247,6 +275,7 @@ public class CategorySearchOptions @JvmOverloads public constructor( private var unsafeParameters: Map? = null private var ignoreIndexableRecords: Boolean = false private var indexableRecordsDistanceThresholdMeters: Double? = null + private var ensureResultsPerCategory: Boolean? = null internal constructor(options: CategorySearchOptions) : this() { proximity = options.proximity @@ -262,6 +291,7 @@ public class CategorySearchOptions @JvmOverloads public constructor( unsafeParameters = options.unsafeParameters ignoreIndexableRecords = options.ignoreIndexableRecords indexableRecordsDistanceThresholdMeters = options.indexableRecordsDistanceThresholdMeters + ensureResultsPerCategory = options.ensureResultsPerCategory } /** @@ -308,7 +338,9 @@ public class CategorySearchOptions @JvmOverloads public constructor( public fun languages(languages: List): Builder = apply { this.languages = languages } /** - * Specify the maximum number of results to return. The maximum supported is 10. + * Specify the maximum number of results to return, including results from [com.mapbox.search.record.IndexableDataProvider]. + * The maximum number of search results is determined by server. For example, + * for the [ApiType.SEARCH_BOX] the maximum number of results to return is 25. */ public fun limit(limit: Int): Builder = apply { this.limit = limit } @@ -371,6 +403,30 @@ public class CategorySearchOptions @JvmOverloads public constructor( this.indexableRecordsDistanceThresholdMeters = threshold } + /** + * When set to true and multiple categories are requested, e.g. + * `SearchEngine.search(listOf("coffee_shop", "hotel"), ...)`, + * results will include at least one POI for each category, provided a POI is available + * in a nearby location. + * + * A comma-separated list of multiple category values in the request determines the sort order + * of the POI result. For example, for request + * `SearchEngine.search(listOf("coffee_shop", "hotel"), ...)`, coffee_shop POI will be listed + * first in the results. + * + * If there is more than one POI for categories, the number of search results will include + * multiple features for each category. For example, assuming that + * restaurant, coffee, parking_lot categories are requested and limit parameter is 10, + * the result will be ranked as follows: + * - 1st to 4th: restaurant POIs + * - 5th to 7th: coffee POIs + * - 8th to 10th: parking_lot POI + */ + @Reserved(SEARCH_BOX) + public fun ensureResultsPerCategory(ensureResultsPerCategory: Boolean?): Builder = apply { + this.ensureResultsPerCategory = ensureResultsPerCategory + } + /** * Create [CategorySearchOptions] instance from builder data. */ @@ -388,6 +444,7 @@ public class CategorySearchOptions @JvmOverloads public constructor( unsafeParameters = unsafeParameters, ignoreIndexableRecords = ignoreIndexableRecords, indexableRecordsDistanceThresholdMeters = indexableRecordsDistanceThresholdMeters, + ensureResultsPerCategory = ensureResultsPerCategory, ) } } @@ -409,4 +466,5 @@ internal fun CategorySearchOptions.mapToCoreCategory(): CoreSearchOptions = crea sarType = routeOptions?.deviation?.sarType?.rawName, timeDeviation = routeOptions?.timeDeviationMinutes, addonAPI = unsafeParameters?.let { (it as? HashMap) ?: HashMap(it) }, + ensureResultsPerCategory = ensureResultsPerCategory, ) diff --git a/MapboxSearch/sdk/src/main/java/com/mapbox/search/SearchEngine.kt b/MapboxSearch/sdk/src/main/java/com/mapbox/search/SearchEngine.kt index e10508da4..c99a0c35f 100644 --- a/MapboxSearch/sdk/src/main/java/com/mapbox/search/SearchEngine.kt +++ b/MapboxSearch/sdk/src/main/java/com/mapbox/search/SearchEngine.kt @@ -270,7 +270,12 @@ public interface SearchEngine { options: CategorySearchOptions, executor: Executor, callback: SearchCallback, - ): AsyncOperationTask + ): AsyncOperationTask = search( + categoryNames = listOf(categoryName), + options = options, + executor = executor, + callback = callback, + ) /** * Performs a search request for places based on a category. @@ -285,7 +290,41 @@ public interface SearchEngine { options: CategorySearchOptions, callback: SearchCallback, ): AsyncOperationTask = search( - categoryName = categoryName, + categoryNames = listOf(categoryName), + options = options, + callback = callback, + ) + + /** + * Performs a search request for places based on multiple categories. + * + * @param categoryNames Multiple categories to search. + * @param options Category search options. + * @param executor Executor used for events dispatching. By default events are dispatched on the main thread. + * @param callback Search callback to retrieve results. + * @return [AsyncOperationTask] object representing pending completion of the request. + */ + public fun search( + categoryNames: List, + options: CategorySearchOptions, + executor: Executor, + callback: SearchCallback, + ): AsyncOperationTask + + /** + * Performs a search request for places based on multiple categories. + * + * @param categoryNames Multiple categories to search. + * @param options Category search options. + * @param callback Search callback to retrieve results. Events are dispatched on the main thread. + * @return [AsyncOperationTask] object representing pending completion of the request. + */ + public fun search( + categoryNames: List, + options: CategorySearchOptions, + callback: SearchCallback, + ): AsyncOperationTask = search( + categoryNames = categoryNames, options = options, executor = SearchSdkMainThreadWorker.mainExecutor, callback = callback, diff --git a/MapboxSearch/sdk/src/main/java/com/mapbox/search/SearchEngineImpl.kt b/MapboxSearch/sdk/src/main/java/com/mapbox/search/SearchEngineImpl.kt index 4fda0b49b..b904c366d 100644 --- a/MapboxSearch/sdk/src/main/java/com/mapbox/search/SearchEngineImpl.kt +++ b/MapboxSearch/sdk/src/main/java/com/mapbox/search/SearchEngineImpl.kt @@ -348,7 +348,7 @@ internal class SearchEngineImpl( } override fun search( - categoryName: String, + categoryNames: List, options: CategorySearchOptions, executor: Executor, callback: SearchCallback, @@ -359,7 +359,7 @@ internal class SearchEngineImpl( val requestContext = requestContextProvider.provide(apiType.mapToCore()) val requestId = coreEngine.search( "", - listOf(categoryName), + categoryNames, options.mapToCoreCategory(), OneStepRequestCallbackWrapper( searchResultFactory = searchResultFactory, diff --git a/MapboxSearch/sdk/src/test/java/com/mapbox/search/CategorySearchOptionsTest.kt b/MapboxSearch/sdk/src/test/java/com/mapbox/search/CategorySearchOptionsTest.kt index 1d13514c8..39924fd45 100644 --- a/MapboxSearch/sdk/src/test/java/com/mapbox/search/CategorySearchOptionsTest.kt +++ b/MapboxSearch/sdk/src/test/java/com/mapbox/search/CategorySearchOptionsTest.kt @@ -49,6 +49,7 @@ internal class CategorySearchOptionsTest { unsafeParameters = null, ignoreIndexableRecords = false, indexableRecordsDistanceThresholdMeters = null, + ensureResultsPerCategory = null, ) Then("Options should be equal", expectedOptions, actualOptions) @@ -75,6 +76,7 @@ internal class CategorySearchOptionsTest { .unsafeParameters(TEST_UNSAFE_PARAMETERS) .ignoreIndexableRecords(true) .indexableRecordsDistanceThresholdMeters(50.0) + .ensureResultsPerCategory(true) .build() val expectedOptions = CategorySearchOptions( @@ -91,6 +93,7 @@ internal class CategorySearchOptionsTest { unsafeParameters = TEST_UNSAFE_PARAMETERS, ignoreIndexableRecords = true, indexableRecordsDistanceThresholdMeters = 50.0, + ensureResultsPerCategory = true, ) Then("Options should be equal", expectedOptions, actualOptions) @@ -117,6 +120,7 @@ internal class CategorySearchOptionsTest { .unsafeParameters(TEST_UNSAFE_PARAMETERS) .ignoreIndexableRecords(true) .indexableRecordsDistanceThresholdMeters(100.123) + .ensureResultsPerCategory(true) .build() val expectedOptions = CategorySearchOptions( @@ -133,6 +137,7 @@ internal class CategorySearchOptionsTest { unsafeParameters = TEST_UNSAFE_PARAMETERS, ignoreIndexableRecords = true, indexableRecordsDistanceThresholdMeters = 100.123, + ensureResultsPerCategory = true, ) Then("Options should be equal", expectedOptions, actualOptions) @@ -174,6 +179,7 @@ internal class CategorySearchOptionsTest { .unsafeParameters(TEST_UNSAFE_PARAMETERS) .ignoreIndexableRecords(true) .indexableRecordsDistanceThresholdMeters(10.0) + .ensureResultsPerCategory(true) .build() val actualOptions = originalOptions.mapToCoreCategory() @@ -195,7 +201,8 @@ internal class CategorySearchOptionsTest { route = TEST_ROUTE_OPTIONS.route, sarType = "isochrone", timeDeviation = TEST_ROUTE_OPTIONS.timeDeviationMinutes, - addonAPI = HashMap(TEST_UNSAFE_PARAMETERS) + addonAPI = HashMap(TEST_UNSAFE_PARAMETERS), + ensureResultsPerCategory = true, ) Then("Options should be equal", expectedOptions, actualOptions) @@ -221,6 +228,7 @@ internal class CategorySearchOptionsTest { unsafeParameters = TEST_UNSAFE_PARAMETERS, ignoreIndexableRecords = true, indexableRecordsDistanceThresholdMeters = 15.0, + ensureResultsPerCategory = true, ) Then("Options should be equal", options, options.toBuilder().build()) diff --git a/MapboxSearch/sdk/src/test/java/com/mapbox/search/CategorySearchTest.kt b/MapboxSearch/sdk/src/test/java/com/mapbox/search/CategorySearchTest.kt index ef5a8a71e..8079a11b1 100644 --- a/MapboxSearch/sdk/src/test/java/com/mapbox/search/CategorySearchTest.kt +++ b/MapboxSearch/sdk/src/test/java/com/mapbox/search/CategorySearchTest.kt @@ -94,7 +94,7 @@ internal class CategorySearchTest { val callback = mockk(relaxed = true) val task = searchEngine.search( - categoryName = TEST_CATEGORIES_QUERY, + categoryName = TEST_CATEGORY_QUERY, options = TEST_SEARCH_OPTIONS, executor = executor, callback = callback @@ -109,7 +109,70 @@ internal class CategorySearchTest { Verify("CoreSearchEngine.search() called") { coreEngine.search( eq(""), - eq(listOf(TEST_CATEGORIES_QUERY)), + eq(listOf(TEST_CATEGORY_QUERY)), + eq(TEST_SEARCH_OPTIONS.mapToCoreCategory()), + slotSearchCallback.captured + ) + } + + Verify("Results passed to callback") { + callback.onResults( + listOf(SearchResult(TEST_SEARCH_RESULT)), + ResponseInfo( + TEST_REQUEST_OPTIONS, + TEST_SUCCESSFUL_CORE_RESPONSE.mapToBase(), + isReproducible = true + ) + ) + } + + VerifyNo("Request is not cancelled") { + coreEngine.cancel(any()) + } + + VerifyOnce("User activity reported") { + activityReporter.reportActivity(eq("search-engine-category-search")) + } + } + } + } + + @TestFactory + fun `Check successful multiple categories search`() = TestCase { + Given("CategorySearchEngine with mocked dependencies") { + + val slotSuggestionCallback = slot<(Result) -> Unit>() + every { searchResultFactory.createSearchSuggestionAsync(any(), any(), any(), any(), capture(slotSuggestionCallback)) }.answers { + slotSuggestionCallback.captured(Result.success(TEST_SEARCH_SUGGESTION)) + AsyncOperationTaskImpl.COMPLETED + } + + val slotSearchCallback = slot() + every { coreEngine.search(any(), any(), any(), capture(slotSearchCallback)) }.answers { + slotSearchCallback.captured.run(TEST_SUCCESSFUL_CORE_RESPONSE) + TEST_REQUEST_ID + } + + When("Multiple categories search called") { + val callback = mockk(relaxed = true) + + val task = searchEngine.search( + categoryNames = TEST_CATEGORIES_QUERY, + options = TEST_SEARCH_OPTIONS, + executor = executor, + callback = callback + ) + + Then("Task is executed", true, task.isDone) + + Verify("Callbacks called inside executor") { + executor.execute(any()) + } + + Verify("CoreSearchEngine.search() called") { + coreEngine.search( + eq(""), + eq(TEST_CATEGORIES_QUERY), eq(TEST_SEARCH_OPTIONS.mapToCoreCategory()), slotSearchCallback.captured ) @@ -152,7 +215,7 @@ internal class CategorySearchTest { val callback = mockk(relaxed = true) val task = searchEngine.search( - categoryName = TEST_CATEGORIES_QUERY, + categoryName = TEST_CATEGORY_QUERY, options = TEST_SEARCH_OPTIONS, executor = executor, callback = callback @@ -167,7 +230,7 @@ internal class CategorySearchTest { Verify("CoreSearchEngine.search() called") { coreEngine.search( eq(""), - eq(listOf(TEST_CATEGORIES_QUERY)), + eq(listOf(TEST_CATEGORY_QUERY)), slotSearchOptions.captured, slotSearchCallback.captured ) @@ -217,7 +280,7 @@ internal class CategorySearchTest { every { callback.onError(capture(slotCallbackError)) } returns Unit searchEngine.search( - categoryName = TEST_CATEGORIES_QUERY, + categoryName = TEST_CATEGORY_QUERY, options = TEST_SEARCH_OPTIONS, executor = executor, callback = callback @@ -248,7 +311,7 @@ internal class CategorySearchTest { val cancellationReason = "Request cancelled" val slotSearchCallback = slot() - every { coreEngine.search(eq(""), eq(listOf(TEST_CATEGORIES_QUERY)), any(), capture(slotSearchCallback)) } answers { + every { coreEngine.search(eq(""), eq(listOf(TEST_CATEGORY_QUERY)), any(), capture(slotSearchCallback)) } answers { slotSearchCallback.captured.run(createTestCoreSearchResponseCancelled(cancellationReason)) TEST_REQUEST_ID } @@ -256,7 +319,7 @@ internal class CategorySearchTest { When("Search request cancelled by the Search SDK") { val callback = mockk(relaxed = true) - val task = searchEngine.search(TEST_CATEGORIES_QUERY, TEST_SEARCH_OPTIONS, callback) + val task = searchEngine.search(TEST_CATEGORY_QUERY, TEST_SEARCH_OPTIONS, callback) Then("Task is cancelled", true, task.isCancelled) @@ -278,14 +341,14 @@ internal class CategorySearchTest { @TestFactory fun `Check search call cancellation initiated by user`() = TestCase { Given("SearchEngine with mocked dependencies") { - every { coreEngine.search(eq(""), eq(listOf(TEST_CATEGORIES_QUERY)), any(), any()) } answers { + every { coreEngine.search(eq(""), eq(listOf(TEST_CATEGORY_QUERY)), any(), any()) } answers { TEST_REQUEST_ID } When("Search request cancelled by user") { val callback = mockk(relaxed = true) - val task = searchEngine.search(TEST_CATEGORIES_QUERY, TEST_SEARCH_OPTIONS, callback) + val task = searchEngine.search(TEST_CATEGORY_QUERY, TEST_SEARCH_OPTIONS, callback) task.cancel() Then("Task is marked as cancelled", true, task.isCancelled) @@ -310,7 +373,8 @@ internal class CategorySearchTest { const val TEST_REQUEST_ID = 1L - const val TEST_CATEGORIES_QUERY = "cafe" + const val TEST_CATEGORY_QUERY = "cafe" + val TEST_CATEGORIES_QUERY = listOf("cafe", "hotel") val TEST_SEARCH_OPTIONS = CategorySearchOptions()