diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5379258b8..f5d191e00 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,19 @@
# Changelog for the Mapbox Search SDK for Android
+## 2.6.1
+
+### New features
+- Added experimental Details API that provides access to POI metadata, boundary details, addresses and places. See `DetailsApi` type.
+
+### Bug fixes
+- Fixed `OpenHours` parsing for the Search Box Api type.
+
+### Mapbox dependencies
+- Search Native SDK `2.6.2`
+- Common SDK `24.8.0`
+
+
+
## 2.6.0
### Mapbox dependencies
diff --git a/MapboxSearch/base/src/main/java/com/mapbox/search/base/ExperimentalMapboxSearchAPI.kt b/MapboxSearch/base/src/main/java/com/mapbox/search/base/ExperimentalMapboxSearchAPI.kt
new file mode 100644
index 000000000..c5b7dfec9
--- /dev/null
+++ b/MapboxSearch/base/src/main/java/com/mapbox/search/base/ExperimentalMapboxSearchAPI.kt
@@ -0,0 +1,19 @@
+package com.mapbox.search.base
+
+/**
+ * This annotation marks the experimental state of the Mapbox Search SDK API.
+ * This API is stable in nature, but it's likely that properties might be added or removed in the
+ * future.
+ * Any usage of a declaration annotated with `@ExperimentalMapboxSearchAPI` must be accepted
+ * either by annotating that usage with the [OptIn] annotation,
+ * e.g. `@OptIn(ExperimentalMapboxSearchAPI::class)`, or by using the compiler argument
+ * `-Xopt-in=com.mapbox.search.base.ExperimentalMapboxSearchAPI`.
+ */
+@Retention(value = AnnotationRetention.BINARY)
+@RequiresOptIn(level = RequiresOptIn.Level.ERROR)
+@Target(
+ AnnotationTarget.CLASS,
+ AnnotationTarget.FUNCTION,
+ AnnotationTarget.PROPERTY,
+)
+annotation class ExperimentalMapboxSearchAPI
diff --git a/MapboxSearch/gradle.properties b/MapboxSearch/gradle.properties
index 52f0ccf55..c31ec12f1 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.6.0
+VERSION_NAME=2.6.1
# Artifact attributes
mapboxArtifactUserOrg=mapbox
diff --git a/MapboxSearch/gradle/versions.gradle b/MapboxSearch/gradle/versions.gradle
index d0d39fa3c..038d65e36 100644
--- a/MapboxSearch/gradle/versions.gradle
+++ b/MapboxSearch/gradle/versions.gradle
@@ -47,7 +47,7 @@ ext {
common_sdk_version = '24.8.0'
mapbox_base_version = '0.8.0'
- search_native_version = '2.6.0'
+ search_native_version = '2.6.2'
detekt_version = '1.19.0'
diff --git a/MapboxSearch/sample/src/main/AndroidManifest.xml b/MapboxSearch/sample/src/main/AndroidManifest.xml
index e42852470..bccc82d09 100644
--- a/MapboxSearch/sample/src/main/AndroidManifest.xml
+++ b/MapboxSearch/sample/src/main/AndroidManifest.xml
@@ -68,6 +68,7 @@
+
diff --git a/MapboxSearch/sample/src/main/java/com/mapbox/search/sample/MainActivity.kt b/MapboxSearch/sample/src/main/java/com/mapbox/search/sample/MainActivity.kt
index b4502cfa2..3999af88e 100644
--- a/MapboxSearch/sample/src/main/java/com/mapbox/search/sample/MainActivity.kt
+++ b/MapboxSearch/sample/src/main/java/com/mapbox/search/sample/MainActivity.kt
@@ -56,6 +56,7 @@ import com.mapbox.search.sample.api.CategorySearchJavaExampleActivity
import com.mapbox.search.sample.api.CategorySearchKotlinExampleActivity
import com.mapbox.search.sample.api.CustomIndexableDataProviderJavaExample
import com.mapbox.search.sample.api.CustomIndexableDataProviderKotlinExample
+import com.mapbox.search.sample.api.DetailsApiKotlinExampleActivity
import com.mapbox.search.sample.api.DiscoverJavaExampleActivity
import com.mapbox.search.sample.api.DiscoverKotlinExampleActivity
import com.mapbox.search.sample.api.FavoritesDataProviderJavaExample
@@ -477,6 +478,10 @@ class MainActivity : AppCompatActivity() {
startActivity(Intent(this, JapanSearchKotlinExampleActivity::class.java))
true
}
+ R.id.open_details_api_kt_example -> {
+ startActivity(Intent(this, DetailsApiKotlinExampleActivity::class.java))
+ true
+ }
R.id.open_japan_search_java_example -> {
startActivity(Intent(this, JapanSearchJavaExampleActivity::class.java))
true
diff --git a/MapboxSearch/sample/src/main/java/com/mapbox/search/sample/api/DetailsApiKotlinExampleActivity.kt b/MapboxSearch/sample/src/main/java/com/mapbox/search/sample/api/DetailsApiKotlinExampleActivity.kt
new file mode 100644
index 000000000..3c2e97dc5
--- /dev/null
+++ b/MapboxSearch/sample/src/main/java/com/mapbox/search/sample/api/DetailsApiKotlinExampleActivity.kt
@@ -0,0 +1,53 @@
+package com.mapbox.search.sample.api
+
+import android.os.Bundle
+import com.mapbox.search.AttributeSet
+import com.mapbox.search.ResponseInfo
+import com.mapbox.search.SearchResultCallback
+import com.mapbox.search.base.ExperimentalMapboxSearchAPI
+import com.mapbox.search.common.AsyncOperationTask
+import com.mapbox.search.details.DetailsApi
+import com.mapbox.search.details.DetailsApiSettings
+import com.mapbox.search.details.RetrieveDetailsOptions
+import com.mapbox.search.result.SearchResult
+import com.mapbox.search.sample.R
+
+@OptIn(ExperimentalMapboxSearchAPI::class)
+class DetailsApiKotlinExampleActivity : BaseKotlinExampleActivity() {
+
+ override val titleResId: Int = R.string.action_open_details_api_kt_example
+
+ private lateinit var detailsApi: DetailsApi
+ private var task: AsyncOperationTask? = null
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ // Set your Access Token here if it's not already set in some other way
+ // MapboxOptions.accessToken = ""
+ detailsApi = DetailsApi.create(DetailsApiSettings())
+ }
+
+ override fun onDestroy() {
+ task?.cancel()
+ super.onDestroy()
+ }
+
+ override fun startExample() {
+ task = detailsApi.retrieveDetails(
+ mapboxId = "dXJuOm1ieHBvaTowZGY2MzE4Yi0wNGNjLTRkOTYtYTZmMy0yNmJmM2ZiODUyODU",
+ options = RetrieveDetailsOptions(attributeSets = AttributeSet.values().toList()),
+ callback = object : SearchResultCallback {
+ override fun onResult(result: SearchResult, responseInfo: ResponseInfo) {
+ logI("SearchApiExample", "Retrieve result:", result)
+ onFinished()
+ }
+
+ override fun onError(e: Exception) {
+ logE("SearchApiExample", "Retrieve error", e)
+ onFinished()
+ }
+ }
+ )
+ }
+}
diff --git a/MapboxSearch/sample/src/main/res/menu/main_activity_options_menu.xml b/MapboxSearch/sample/src/main/res/menu/main_activity_options_menu.xml
index 2d41f218b..50a0e0315 100644
--- a/MapboxSearch/sample/src/main/res/menu/main_activity_options_menu.xml
+++ b/MapboxSearch/sample/src/main/res/menu/main_activity_options_menu.xml
@@ -94,6 +94,11 @@
android:title="@string/action_open_japan_search_kt_example"
/>
+
+
- Favorites Data Provider
Custom data provider
Custom data provider
+ Details API
Offline Search Along Route
diff --git a/MapboxSearch/sdk/api/api-metalava.txt b/MapboxSearch/sdk/api/api-metalava.txt
index 2925cea4d..4b9b5cce0 100644
--- a/MapboxSearch/sdk/api/api-metalava.txt
+++ b/MapboxSearch/sdk/api/api-metalava.txt
@@ -604,6 +604,50 @@ package com.mapbox.search.analytics {
}
+package com.mapbox.search.details {
+
+ @com.mapbox.search.base.ExperimentalMapboxSearchAPI public interface DetailsApi {
+ method public default static com.mapbox.search.details.DetailsApi create(com.mapbox.search.details.DetailsApiSettings settings = DetailsApiSettings());
+ method public default static final com.mapbox.search.details.DetailsApi create();
+ method public default com.mapbox.search.common.AsyncOperationTask retrieveDetails(String mapboxId, com.mapbox.search.details.RetrieveDetailsOptions options, com.mapbox.search.SearchResultCallback callback);
+ method public com.mapbox.search.common.AsyncOperationTask retrieveDetails(String mapboxId, com.mapbox.search.details.RetrieveDetailsOptions options, java.util.concurrent.Executor executor, com.mapbox.search.SearchResultCallback callback);
+ field public static final com.mapbox.search.details.DetailsApi.Companion Companion;
+ }
+
+ public static final class DetailsApi.Companion {
+ method public com.mapbox.search.details.DetailsApi create(com.mapbox.search.details.DetailsApiSettings settings = DetailsApiSettings());
+ method public com.mapbox.search.details.DetailsApi create();
+ }
+
+ @com.mapbox.search.base.ExperimentalMapboxSearchAPI public final class DetailsApiSettings {
+ ctor public DetailsApiSettings(com.mapbox.common.location.LocationProvider? locationProvider = (), com.mapbox.search.ViewportProvider? viewportProvider = null, String? baseUrl = null);
+ ctor public DetailsApiSettings(com.mapbox.common.location.LocationProvider? locationProvider = (), com.mapbox.search.ViewportProvider? viewportProvider = null);
+ ctor public DetailsApiSettings(com.mapbox.common.location.LocationProvider? locationProvider = ());
+ method public String? getBaseUrl();
+ method public com.mapbox.common.location.LocationProvider? getLocationProvider();
+ method public com.mapbox.search.ViewportProvider? getViewportProvider();
+ property public final String? baseUrl;
+ property public final com.mapbox.common.location.LocationProvider? locationProvider;
+ property public final com.mapbox.search.ViewportProvider? viewportProvider;
+ }
+
+ @com.mapbox.search.base.ExperimentalMapboxSearchAPI @kotlinx.parcelize.Parcelize public final class RetrieveDetailsOptions implements android.os.Parcelable {
+ ctor public RetrieveDetailsOptions(java.util.List extends com.mapbox.search.AttributeSet>? attributeSets = null, com.mapbox.search.common.IsoLanguageCode language = (), com.mapbox.search.common.IsoCountryCode? worldview = null);
+ ctor public RetrieveDetailsOptions(java.util.List extends com.mapbox.search.AttributeSet>? attributeSets = null, com.mapbox.search.common.IsoLanguageCode language = ());
+ ctor public RetrieveDetailsOptions(java.util.List extends com.mapbox.search.AttributeSet>? attributeSets = null);
+ method public java.util.List? getAttributeSets();
+ method public com.mapbox.search.common.IsoLanguageCode getLanguage();
+ method public com.mapbox.search.common.IsoCountryCode? getWorldview();
+ property public final java.util.List? attributeSets;
+ property public final com.mapbox.search.common.IsoLanguageCode language;
+ property public final com.mapbox.search.common.IsoCountryCode? worldview;
+ }
+
+ public final class RetrieveDetailsOptionsKt {
+ }
+
+}
+
package com.mapbox.search.record {
@kotlinx.parcelize.Parcelize public final class FavoriteRecord implements com.mapbox.search.record.IndexableRecord android.os.Parcelable {
diff --git a/MapboxSearch/sdk/api/sdk.api b/MapboxSearch/sdk/api/sdk.api
index a57965180..13dbac830 100644
--- a/MapboxSearch/sdk/api/sdk.api
+++ b/MapboxSearch/sdk/api/sdk.api
@@ -736,6 +736,63 @@ public final class com/mapbox/search/analytics/events/SearchResultsInfo$Creator
public synthetic fun newArray (I)[Ljava/lang/Object;
}
+public abstract interface class com/mapbox/search/details/DetailsApi {
+ public static final field Companion Lcom/mapbox/search/details/DetailsApi$Companion;
+ public static fun create ()Lcom/mapbox/search/details/DetailsApi;
+ public static fun create (Lcom/mapbox/search/details/DetailsApiSettings;)Lcom/mapbox/search/details/DetailsApi;
+ public abstract fun retrieveDetails (Ljava/lang/String;Lcom/mapbox/search/details/RetrieveDetailsOptions;Lcom/mapbox/search/SearchResultCallback;)Lcom/mapbox/search/common/AsyncOperationTask;
+ public abstract fun retrieveDetails (Ljava/lang/String;Lcom/mapbox/search/details/RetrieveDetailsOptions;Ljava/util/concurrent/Executor;Lcom/mapbox/search/SearchResultCallback;)Lcom/mapbox/search/common/AsyncOperationTask;
+}
+
+public final class com/mapbox/search/details/DetailsApi$Companion {
+ public final fun create ()Lcom/mapbox/search/details/DetailsApi;
+ public final fun create (Lcom/mapbox/search/details/DetailsApiSettings;)Lcom/mapbox/search/details/DetailsApi;
+ public static synthetic fun create$default (Lcom/mapbox/search/details/DetailsApi$Companion;Lcom/mapbox/search/details/DetailsApiSettings;ILjava/lang/Object;)Lcom/mapbox/search/details/DetailsApi;
+}
+
+public final class com/mapbox/search/details/DetailsApi$DefaultImpls {
+ public static fun retrieveDetails (Lcom/mapbox/search/details/DetailsApi;Ljava/lang/String;Lcom/mapbox/search/details/RetrieveDetailsOptions;Lcom/mapbox/search/SearchResultCallback;)Lcom/mapbox/search/common/AsyncOperationTask;
+}
+
+public final class com/mapbox/search/details/DetailsApiSettings {
+ public fun ()V
+ public fun (Lcom/mapbox/common/location/LocationProvider;)V
+ public fun (Lcom/mapbox/common/location/LocationProvider;Lcom/mapbox/search/ViewportProvider;)V
+ public fun (Lcom/mapbox/common/location/LocationProvider;Lcom/mapbox/search/ViewportProvider;Ljava/lang/String;)V
+ public synthetic fun (Lcom/mapbox/common/location/LocationProvider;Lcom/mapbox/search/ViewportProvider;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+ public fun equals (Ljava/lang/Object;)Z
+ public final fun getBaseUrl ()Ljava/lang/String;
+ public final fun getLocationProvider ()Lcom/mapbox/common/location/LocationProvider;
+ public final fun getViewportProvider ()Lcom/mapbox/search/ViewportProvider;
+ public fun hashCode ()I
+ public fun toString ()Ljava/lang/String;
+}
+
+public final class com/mapbox/search/details/RetrieveDetailsOptions : android/os/Parcelable {
+ public static final field CREATOR Landroid/os/Parcelable$Creator;
+ public fun ()V
+ public fun (Ljava/util/List;)V
+ public fun (Ljava/util/List;Lcom/mapbox/search/common/IsoLanguageCode;)V
+ public fun (Ljava/util/List;Lcom/mapbox/search/common/IsoLanguageCode;Lcom/mapbox/search/common/IsoCountryCode;)V
+ public synthetic fun (Ljava/util/List;Lcom/mapbox/search/common/IsoLanguageCode;Lcom/mapbox/search/common/IsoCountryCode;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
+ public fun describeContents ()I
+ public fun equals (Ljava/lang/Object;)Z
+ public final fun getAttributeSets ()Ljava/util/List;
+ public final fun getLanguage ()Lcom/mapbox/search/common/IsoLanguageCode;
+ public final fun getWorldview ()Lcom/mapbox/search/common/IsoCountryCode;
+ public fun hashCode ()I
+ public fun toString ()Ljava/lang/String;
+ public fun writeToParcel (Landroid/os/Parcel;I)V
+}
+
+public final class com/mapbox/search/details/RetrieveDetailsOptions$Creator : android/os/Parcelable$Creator {
+ public fun ()V
+ public final fun createFromParcel (Landroid/os/Parcel;)Lcom/mapbox/search/details/RetrieveDetailsOptions;
+ public synthetic fun createFromParcel (Landroid/os/Parcel;)Ljava/lang/Object;
+ public final fun newArray (I)[Lcom/mapbox/search/details/RetrieveDetailsOptions;
+ public synthetic fun newArray (I)[Ljava/lang/Object;
+}
+
public final class com/mapbox/search/record/FavoriteRecord : android/os/Parcelable, com/mapbox/search/record/IndexableRecord {
public static final field CREATOR Landroid/os/Parcelable$Creator;
public fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/mapbox/search/result/SearchAddress;Ljava/util/List;Ljava/util/List;Ljava/lang/String;Lcom/mapbox/geojson/Point;Lcom/mapbox/search/result/SearchResultType;Lcom/mapbox/search/SearchResultMetadata;)V
diff --git a/MapboxSearch/sdk/src/androidTest/assets/details_api/response_successful.json b/MapboxSearch/sdk/src/androidTest/assets/details_api/response_successful.json
new file mode 100644
index 000000000..5ae6aba68
--- /dev/null
+++ b/MapboxSearch/sdk/src/androidTest/assets/details_api/response_successful.json
@@ -0,0 +1,186 @@
+{
+ "geometry": {
+ "coordinates": [
+ -77.029129,
+ 38.902309
+ ],
+ "type": "Point"
+ },
+ "properties": {
+ "address": "925 13th St NW",
+ "context": {
+ "address": {
+ "address_number": "925",
+ "id": "",
+ "name": "925 13th St NW, Washington DC, DC 20005-4005",
+ "street_name": "13th st nw"
+ },
+ "country": {
+ "country_code": "US",
+ "country_code_alpha_3": "USA",
+ "id": "",
+ "name": "United States"
+ },
+ "neighborhood": {
+ "id": "dXJuOm1ieHBsYzpDaXpzN0E",
+ "name": "Downtown"
+ },
+ "place": {
+ "id": "dXJuOm1ieHBsYzpGSmlvN0E",
+ "name": "Washington"
+ },
+ "postcode": {
+ "id": "dXJuOm1ieHBsYzpBNTd1N0E",
+ "name": "20005"
+ },
+ "region": {
+ "id": "",
+ "name": "District of Columbia",
+ "region_code": "DC",
+ "region_code_full": "US-DC"
+ },
+ "street": {
+ "id": "",
+ "name": "13th st nw"
+ }
+ },
+ "coordinates": {
+ "latitude": 38.902309,
+ "longitude": -77.029129,
+ "routable_points": [
+ {
+ "latitude": 38.9023073713156,
+ "longitude": -77.0296257487584,
+ "name": "POI"
+ }
+ ]
+ },
+ "external_ids": {
+ "tripadvisor": "20145439"
+ },
+ "feature_type": "poi",
+ "full_address": "925 13th St NW, Washington, District of Columbia 20005, United States",
+ "language": "en",
+ "maki": "marker",
+ "mapbox_id": "dXJuOm1ieHBvaTo0ZTg2ZWFkNS1jOWMwLTQ3OWEtOTA5Mi1kMDVlNDQ3NDdlODk",
+ "metadata": {
+ "open_hours": {
+ "periods": [
+ {
+ "close": {
+ "day": 0,
+ "time": "1800"
+ },
+ "open": {
+ "day": 0,
+ "time": "1000"
+ }
+ },
+ {
+ "close": {
+ "day": 1,
+ "time": "1700"
+ },
+ "open": {
+ "day": 1,
+ "time": "1000"
+ }
+ },
+ {
+ "close": {
+ "day": 3,
+ "time": "1700"
+ },
+ "open": {
+ "day": 3,
+ "time": "1000"
+ }
+ },
+ {
+ "close": {
+ "day": 4,
+ "time": "1700"
+ },
+ "open": {
+ "day": 4,
+ "time": "1000"
+ }
+ },
+ {
+ "close": {
+ "day": 5,
+ "time": "1700"
+ },
+ "open": {
+ "day": 5,
+ "time": "1000"
+ }
+ },
+ {
+ "close": {
+ "day": 6,
+ "time": "1800"
+ },
+ "open": {
+ "day": 6,
+ "time": "1000"
+ }
+ }
+ ],
+ "weekday_text": [
+ "Monday: 10:00 AM - 5:00 PM",
+ "Tuesday: Closed",
+ "Wednesday: 10:00 AM - 5:00 PM",
+ "Thursday: 10:00 AM - 5:00 PM",
+ "Friday: 10:00 AM - 5:00 PM",
+ "Saturday: 10:00 AM - 6:00 PM",
+ "Sunday: 10:00 AM - 6:00 PM"
+ ]
+ },
+ "phone": "+12029313139",
+ "photos": [
+ {
+ "height": 768,
+ "url": "https://media-cdn.tripadvisor.com/media/photo-o/2a/08/ad/cd/caption.jpg",
+ "width": 1024
+ },
+ {
+ "height": 1024,
+ "url": "https://media-cdn.tripadvisor.com/media/photo-o/2a/08/ad/fe/caption.jpg",
+ "width": 768
+ },
+ {
+ "height": 975,
+ "url": "https://media-cdn.tripadvisor.com/media/photo-o/28/b6/2d/cc/caption.jpg",
+ "width": 2006
+ },
+ {
+ "height": 3888,
+ "url": "https://media-cdn.tripadvisor.com/media/photo-o/2a/45/ec/0a/caption.jpg",
+ "width": 5184
+ },
+ {
+ "height": 975,
+ "url": "https://media-cdn.tripadvisor.com/media/photo-o/28/b6/2d/ca/caption.jpg",
+ "width": 2006
+ }
+ ],
+ "primary_photo": "https://media-cdn.tripadvisor.com/media/photo-o/2a/08/ad/cd/caption.jpg",
+ "rating": 5,
+ "review_count": 69,
+ "website": "http://www.planetwordmuseum.org"
+ },
+ "name": "Planet Word",
+ "operational_status": "active",
+ "place_formatted": "Washington, District of Columbia 20005, United States",
+ "poi_category": [
+ "museum",
+ "tourist attraction"
+ ],
+ "poi_category_ids": [
+ "museum",
+ "tourist_attraction"
+ ]
+ },
+ "type": "Feature"
+}
\ No newline at end of file
diff --git a/MapboxSearch/sdk/src/androidTest/java/com/mapbox/search/SearchEngineIntegrationTest.kt b/MapboxSearch/sdk/src/androidTest/java/com/mapbox/search/SearchEngineIntegrationTest.kt
index 0fda778da..c6fc42957 100644
--- a/MapboxSearch/sdk/src/androidTest/java/com/mapbox/search/SearchEngineIntegrationTest.kt
+++ b/MapboxSearch/sdk/src/androidTest/java/com/mapbox/search/SearchEngineIntegrationTest.kt
@@ -1300,9 +1300,9 @@ internal class SearchEngineIntegrationTest : BaseTest() {
searchEngine.retrieve(mapboxId, callback)
val result = callback.getResultBlocking()
- assertTrue(result is SearchResult)
+ assertTrue(result.isSuccess)
- val searchResult = result as SearchResult
+ val searchResult = result.getSuccess().result
assertEquals(mapboxId, searchResult.mapboxId)
}
@@ -1318,7 +1318,7 @@ internal class SearchEngineIntegrationTest : BaseTest() {
searchEngine.retrieve(mapboxId, callback)
val result = callback.getResultBlocking()
- assertTrue(result is Exception)
+ assertTrue(result.isError)
}
@After
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
new file mode 100644
index 000000000..e25896118
--- /dev/null
+++ b/MapboxSearch/sdk/src/androidTest/java/com/mapbox/search/details/DetailsApiIntegrationTest.kt
@@ -0,0 +1,115 @@
+package com.mapbox.search.details
+
+import com.mapbox.common.MapboxOptions
+import com.mapbox.geojson.Point
+import com.mapbox.search.AttributeSet
+import com.mapbox.search.BaseTest
+import com.mapbox.search.MapboxSearchSdk
+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.OpenHours
+import com.mapbox.search.tests_support.BlockingSearchResultCallback
+import com.mapbox.search.utils.assertEqualsIgnoreCase
+import okhttp3.mockwebserver.MockResponse
+import okhttp3.mockwebserver.MockWebServer
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertTrue
+import org.junit.Before
+import org.junit.Test
+
+@OptIn(ExperimentalMapboxSearchAPI::class)
+internal class DetailsApiIntegrationTest : BaseTest() {
+
+ private lateinit var mockServer: MockWebServer
+ private lateinit var detailsApiSettings: DetailsApiSettings
+ private lateinit var detailsApi: DetailsApi
+
+ @Before
+ override fun setUp() {
+ super.setUp()
+ MapboxOptions.accessToken = TEST_ACCESS_TOKEN
+
+ mockServer = MockWebServer()
+
+ MapboxSearchSdk.initialize(
+ application = targetApplication,
+ )
+
+ detailsApiSettings = DetailsApiSettings(
+ baseUrl = mockServer.url("").toString(),
+ )
+
+ detailsApi = DetailsApi.create(detailsApiSettings)
+ }
+
+ @Test
+ fun testRequestParametersAreCorrect() {
+ mockServer.enqueue(MockResponse().setResponseCode(500))
+
+ val options = RetrieveDetailsOptions(
+ attributeSets = listOf(AttributeSet.BASIC, AttributeSet.VISIT, AttributeSet.PHOTOS, AttributeSet.VENUE),
+ language = IsoLanguageCode.FRENCH,
+ worldview = IsoCountryCode.FRANCE,
+ )
+
+ val callback = BlockingSearchResultCallback()
+ detailsApi.retrieveDetails(TEST_MAPBOX_ID, options, callback)
+
+ val request = mockServer.takeRequest()
+ assertEqualsIgnoreCase("get", request.method!!)
+
+ val url = request.requestUrl!!
+ assertEqualsIgnoreCase("//search/details/v1/retrieve/$TEST_MAPBOX_ID", url.encodedPath)
+ assertEquals(TEST_ACCESS_TOKEN, url.queryParameter("access_token"))
+ assertEquals(options.language.code, url.queryParameter("language"))
+ assertEquals(options.worldview!!.code, url.queryParameter("worldview"))
+ assertEquals(
+ options.attributeSets!!.joinToString(separator = ",") { it.name.lowercase() },
+ url.queryParameter("attribute_sets")
+ )
+ }
+
+ @Test
+ fun testSuccessfulResponse() {
+ mockServer.enqueue(createSuccessfulResponse("details_api/response_successful.json"))
+
+ val callback = BlockingSearchResultCallback()
+ detailsApi.retrieveDetails(TEST_MAPBOX_ID, RetrieveDetailsOptions(), callback)
+
+ val requestResult = callback.getResultBlocking()
+ assertTrue(requestResult.isSuccess)
+
+ val searchResult = requestResult.getSuccess().result
+
+ assertEquals("Planet Word", searchResult.name)
+ assertEquals(
+ "dXJuOm1ieHBvaTo0ZTg2ZWFkNS1jOWMwLTQ3OWEtOTA5Mi1kMDVlNDQ3NDdlODk",
+ searchResult.mapboxId,
+ )
+ 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)
+ }
+
+ @Test
+ fun testErrorResponse() {
+ mockServer.enqueue(MockResponse().setResponseCode(404))
+
+ val callback = BlockingSearchResultCallback()
+ detailsApi.retrieveDetails(TEST_MAPBOX_ID, RetrieveDetailsOptions(), callback)
+
+ val requestResult = callback.getResultBlocking()
+ assertTrue(requestResult.isError)
+
+ val e = requestResult.getError().e
+ assertTrue(e is SearchRequestException && e.code == 404)
+ }
+
+ private companion object {
+ const val TEST_ACCESS_TOKEN = "pk.test"
+ const val TEST_MAPBOX_ID = "test-id"
+ }
+}
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 cefb0c238..8ee86122f 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
@@ -208,8 +208,8 @@ internal class ReverseGeocodingSearchIntegrationTest : BaseTest() {
openHours = OpenHours.Scheduled(
periods = listOf(
OpenPeriod(
- open = WeekTimestamp(WeekDay.MONDAY, 9, 0),
- closed = WeekTimestamp(WeekDay.MONDAY, 23, 45)
+ open = WeekTimestamp(WeekDay.SUNDAY, 9, 0),
+ closed = WeekTimestamp(WeekDay.SUNDAY, 23, 45)
)
)
),
diff --git a/MapboxSearch/sdk/src/androidTest/java/com/mapbox/search/search_box/SearchEngineIntegrationTest.kt b/MapboxSearch/sdk/src/androidTest/java/com/mapbox/search/search_box/SearchEngineIntegrationTest.kt
index 460e6767d..de31934e6 100644
--- a/MapboxSearch/sdk/src/androidTest/java/com/mapbox/search/search_box/SearchEngineIntegrationTest.kt
+++ b/MapboxSearch/sdk/src/androidTest/java/com/mapbox/search/search_box/SearchEngineIntegrationTest.kt
@@ -661,8 +661,8 @@ internal class SearchEngineIntegrationTest : BaseTest() {
OpenHours.Scheduled(
periods = listOf(
OpenPeriod(
- open = WeekTimestamp(WeekDay.SATURDAY, 7, 0),
- closed = WeekTimestamp(WeekDay.SATURDAY, 20, 0)
+ open = WeekTimestamp(WeekDay.FRIDAY, 7, 0),
+ closed = WeekTimestamp(WeekDay.FRIDAY, 20, 0)
)
)
), openHours
@@ -957,7 +957,7 @@ internal class SearchEngineIntegrationTest : BaseTest() {
searchEngine.retrieve(mapboxId, callback)
val result = callback.getResultBlocking()
- assertTrue(result is Exception)
+ assertTrue(result.isError)
}
@Test
diff --git a/MapboxSearch/sdk/src/androidTest/java/com/mapbox/search/tests_support/BlockingSearchResultCallback.kt b/MapboxSearch/sdk/src/androidTest/java/com/mapbox/search/tests_support/BlockingSearchResultCallback.kt
index b362ec354..2d4359a4b 100644
--- a/MapboxSearch/sdk/src/androidTest/java/com/mapbox/search/tests_support/BlockingSearchResultCallback.kt
+++ b/MapboxSearch/sdk/src/androidTest/java/com/mapbox/search/tests_support/BlockingSearchResultCallback.kt
@@ -5,13 +5,30 @@ import com.mapbox.search.SearchResultCallback
import com.mapbox.search.common.tests.BaseBlockingCallback
import com.mapbox.search.result.SearchResult
-internal class BlockingSearchResultCallback : SearchResultCallback, BaseBlockingCallback() {
+internal class BlockingSearchResultCallback :
+ SearchResultCallback,
+ BaseBlockingCallback() {
override fun onResult(result: SearchResult, responseInfo: ResponseInfo) {
- publishResult(result)
+ publishResult(Result.Success(result, responseInfo))
}
override fun onError(e: Exception) {
- publishResult(e)
+ publishResult(Result.Error(e))
+ }
+
+ sealed class Result {
+
+ val isSuccess: Boolean
+ get() = this is Success
+
+ val isError: Boolean
+ get() = !isSuccess
+
+ fun getSuccess() = this as Success
+ fun getError() = this as Error
+
+ data class Success(val result: SearchResult, val responseInfo: ResponseInfo) : Result()
+ data class Error(val e: Exception) : Result()
}
}
diff --git a/MapboxSearch/sdk/src/main/java/com/mapbox/search/SearchEngineFactory.kt b/MapboxSearch/sdk/src/main/java/com/mapbox/search/SearchEngineFactory.kt
index e8f0a3f9b..da48b8ec4 100644
--- a/MapboxSearch/sdk/src/main/java/com/mapbox/search/SearchEngineFactory.kt
+++ b/MapboxSearch/sdk/src/main/java/com/mapbox/search/SearchEngineFactory.kt
@@ -1,5 +1,6 @@
package com.mapbox.search
+import com.mapbox.common.location.LocationProvider
import com.mapbox.search.analytics.AnalyticsService
import com.mapbox.search.base.BaseSearchSdkInitializerImpl
import com.mapbox.search.base.StubCompletionCallback
@@ -93,18 +94,32 @@ internal class SearchEngineFactory {
else -> null
}
+ return createCoreEngineByApiType(
+ apiType = apiType,
+ baseUrl = baseUrl,
+ locationProvider = settings.locationProvider,
+ viewportProvider = settings.viewportProvider,
+ )
+ }
+
+ fun createCoreEngineByApiType(
+ apiType: ApiType,
+ baseUrl: String?,
+ locationProvider: LocationProvider?,
+ viewportProvider: ViewportProvider?,
+ ): CoreSearchEngineInterface {
// Workaround for sync location provider in test environment.
// Needed while https://github.com/mapbox/mapbox-search-sdk/issues/671 not fixed
- val coreLocationProvider = if (settings.locationProvider is CoreLocationProvider) {
- settings.locationProvider
+ val coreLocationProvider = if (locationProvider is CoreLocationProvider) {
+ locationProvider
} else {
WrapperLocationProvider(
LocationEngineAdapter(
BaseSearchSdkInitializerImpl.app,
- settings.locationProvider
+ locationProvider
)
) {
- settings.viewportProvider?.getViewport()?.mapToCore()
+ viewportProvider?.getViewport()?.mapToCore()
}
}
diff --git a/MapboxSearch/sdk/src/main/java/com/mapbox/search/details/DetailsApi.kt b/MapboxSearch/sdk/src/main/java/com/mapbox/search/details/DetailsApi.kt
new file mode 100644
index 000000000..315491248
--- /dev/null
+++ b/MapboxSearch/sdk/src/main/java/com/mapbox/search/details/DetailsApi.kt
@@ -0,0 +1,94 @@
+package com.mapbox.search.details
+
+import com.mapbox.search.ApiType
+import com.mapbox.search.MapboxSearchSdk
+import com.mapbox.search.SearchEngineFactory
+import com.mapbox.search.SearchResultCallback
+import com.mapbox.search.base.ExperimentalMapboxSearchAPI
+import com.mapbox.search.base.core.getUserActivityReporter
+import com.mapbox.search.common.AsyncOperationTask
+import com.mapbox.search.common.concurrent.SearchSdkMainThreadWorker
+import java.util.concurrent.Executor
+
+/**
+ * The Details API provides access to POI metadata, boundary details, addresses and places.
+ * For more information, visit [Details API page](https://docs.mapbox.com/api/search/details/).
+ *
+ * Instance of the [DetailsApi] can be obtained with [DetailsApi.create].
+ */
+@ExperimentalMapboxSearchAPI
+public interface DetailsApi {
+
+ /**
+ * Request basic metadata for a POI, which includes attributes such as POI name, address,
+ * coordinates, primary photo and category classification.
+ *
+ * To retrieve additional attributes beyond the basic data for a POI,
+ * specify [RetrieveDetailsOptions.attributeSets] in the provided [options].
+ *
+ * @param mapboxId A unique identifier for the geographic feature.
+ * @param options Retrieve options.
+ * @param callback Search result callback. Events are dispatched on the main thread.
+ * @return [AsyncOperationTask] object representing pending completion of the request
+ */
+ public fun retrieveDetails(
+ mapboxId: String,
+ options: RetrieveDetailsOptions,
+ callback: SearchResultCallback,
+ ): AsyncOperationTask = retrieveDetails(
+ mapboxId = mapboxId,
+ options = options,
+ executor = SearchSdkMainThreadWorker.mainExecutor,
+ callback = callback,
+ )
+
+ /**
+ * Request basic metadata for a POI, which includes attributes such as POI name, address,
+ * coordinates, primary photo and category classification.
+ *
+ * To retrieve additional attributes beyond the basic data for a POI,
+ * specify [RetrieveDetailsOptions.attributeSets] in the provided [options].
+ *
+ * @param mapboxId A unique identifier for the geographic feature.
+ * @param options Retrieve options.
+ * @param executor [Executor] used for events dispatching, default is the main thread.
+ * @param callback Search result callback.
+ * @return [AsyncOperationTask] object representing pending completion of the request
+ */
+ public fun retrieveDetails(
+ mapboxId: String,
+ options: RetrieveDetailsOptions,
+ executor: Executor,
+ callback: SearchResultCallback,
+ ): AsyncOperationTask
+
+ /**
+ * Companion object.
+ */
+ public companion object {
+
+ /**
+ * Creates a new instance of the [DetailsApi].
+ *
+ * @param settings [DetailsApiSettings] settings.
+ * @return a new instance instance of the [DetailsApi].
+ */
+ @JvmStatic
+ @JvmOverloads
+ public fun create(settings: DetailsApiSettings = DetailsApiSettings()): DetailsApi {
+ val coreEngine = SearchEngineFactory().createCoreEngineByApiType(
+ apiType = ApiType.SEARCH_BOX,
+ baseUrl = settings.baseUrl,
+ locationProvider = settings.locationProvider,
+ viewportProvider = settings.viewportProvider,
+ )
+
+ return DetailsApiImpl(
+ coreEngine,
+ getUserActivityReporter(),
+ MapboxSearchSdk.searchRequestContextProvider,
+ MapboxSearchSdk.searchResultFactory,
+ )
+ }
+ }
+}
diff --git a/MapboxSearch/sdk/src/main/java/com/mapbox/search/details/DetailsApiImpl.kt b/MapboxSearch/sdk/src/main/java/com/mapbox/search/details/DetailsApiImpl.kt
new file mode 100644
index 000000000..80ae5a63b
--- /dev/null
+++ b/MapboxSearch/sdk/src/main/java/com/mapbox/search/details/DetailsApiImpl.kt
@@ -0,0 +1,62 @@
+package com.mapbox.search.details
+
+import com.mapbox.search.SearchResultCallback
+import com.mapbox.search.adapter.SearchResultCallbackAdapter
+import com.mapbox.search.base.ExperimentalMapboxSearchAPI
+import com.mapbox.search.base.SearchRequestContextProvider
+import com.mapbox.search.base.core.CoreApiType
+import com.mapbox.search.base.core.CoreSearchEngineInterface
+import com.mapbox.search.base.engine.BaseSearchEngine
+import com.mapbox.search.base.engine.OneStepRequestCallbackWrapper
+import com.mapbox.search.base.result.SearchResultFactory
+import com.mapbox.search.common.AsyncOperationTask
+import com.mapbox.search.internal.bindgen.UserActivityReporterInterface
+import java.util.concurrent.Executor
+import java.util.concurrent.ExecutorService
+import java.util.concurrent.Executors
+
+@OptIn(ExperimentalMapboxSearchAPI::class)
+internal class DetailsApiImpl(
+ private val coreEngine: CoreSearchEngineInterface,
+ private val activityReporter: UserActivityReporterInterface,
+ private val requestContextProvider: SearchRequestContextProvider,
+ private val searchResultFactory: SearchResultFactory,
+ private val engineExecutorService: ExecutorService = DEFAULT_EXECUTOR,
+) : BaseSearchEngine(), DetailsApi {
+
+ override fun retrieveDetails(
+ mapboxId: String,
+ options: RetrieveDetailsOptions,
+ executor: Executor,
+ callback: SearchResultCallback
+ ): AsyncOperationTask {
+ activityReporter.reportActivity("details-api-retrieve")
+
+ val baseCallback = SearchResultCallbackAdapter(callback)
+
+ return makeRequest(baseCallback) { task ->
+ val requestId = coreEngine.retrieveDetails(
+ mapboxId,
+ options.mapToCore(),
+ OneStepRequestCallbackWrapper(
+ searchResultFactory = searchResultFactory,
+ callbackExecutor = executor,
+ workerExecutor = engineExecutorService,
+ searchRequestTask = task,
+ searchRequestContext = requestContextProvider.provide(CoreApiType.SEARCH_BOX),
+ isOffline = false,
+ )
+ )
+
+ task.addOnCancelledCallback {
+ coreEngine.cancel(requestId)
+ }
+ }
+ }
+
+ private companion object {
+ val DEFAULT_EXECUTOR: ExecutorService = Executors.newSingleThreadExecutor { runnable ->
+ Thread(runnable, "DetailsApi executor")
+ }
+ }
+}
diff --git a/MapboxSearch/sdk/src/main/java/com/mapbox/search/details/DetailsApiSettings.kt b/MapboxSearch/sdk/src/main/java/com/mapbox/search/details/DetailsApiSettings.kt
new file mode 100644
index 000000000..ed2728237
--- /dev/null
+++ b/MapboxSearch/sdk/src/main/java/com/mapbox/search/details/DetailsApiSettings.kt
@@ -0,0 +1,72 @@
+package com.mapbox.search.details
+
+import android.Manifest
+import com.mapbox.common.location.LocationProvider
+import com.mapbox.common.location.LocationServiceFactory
+import com.mapbox.search.ViewportProvider
+import com.mapbox.search.base.ExperimentalMapboxSearchAPI
+import com.mapbox.search.base.location.defaultLocationProvider
+
+/**
+ * Settings used for [DetailsApi] configuration.
+ * @see DetailsApi
+ */
+@ExperimentalMapboxSearchAPI
+public class DetailsApiSettings @JvmOverloads constructor(
+
+ /**
+ * The mechanism responsible for providing location approximations to the SDK.
+ * By default [LocationProvider] is provided by [LocationServiceFactory].
+ * Note that this class requires [Manifest.permission.ACCESS_COARSE_LOCATION] or
+ * [Manifest.permission.ACCESS_FINE_LOCATION] to work properly.
+ */
+ public val locationProvider: LocationProvider? = defaultLocationProvider(),
+
+ /**
+ * Viewport provider instance.
+ */
+ public val viewportProvider: ViewportProvider? = null,
+
+ /**
+ * Base endpoint URL.
+ */
+ public val baseUrl: String? = null,
+) {
+
+ /**
+ * @suppress
+ */
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (javaClass != other?.javaClass) return false
+
+ other as DetailsApiSettings
+
+ if (locationProvider != other.locationProvider) return false
+ if (viewportProvider != other.viewportProvider) return false
+ if (baseUrl != other.baseUrl) return false
+
+ return true
+ }
+
+ /**
+ * @suppress
+ */
+ override fun hashCode(): Int {
+ var result = locationProvider?.hashCode() ?: 0
+ result = 31 * result + (viewportProvider?.hashCode() ?: 0)
+ result = 31 * result + (baseUrl?.hashCode() ?: 0)
+ return result
+ }
+
+ /**
+ * @suppress
+ */
+ override fun toString(): String {
+ return "DetailsApiSettings(" +
+ "locationProvider=$locationProvider, " +
+ "viewportProvider=$viewportProvider, " +
+ "baseUrl=$baseUrl" +
+ ")"
+ }
+}
diff --git a/MapboxSearch/sdk/src/main/java/com/mapbox/search/details/RetrieveDetailsOptions.kt b/MapboxSearch/sdk/src/main/java/com/mapbox/search/details/RetrieveDetailsOptions.kt
new file mode 100644
index 000000000..642aed47a
--- /dev/null
+++ b/MapboxSearch/sdk/src/main/java/com/mapbox/search/details/RetrieveDetailsOptions.kt
@@ -0,0 +1,96 @@
+package com.mapbox.search.details
+
+import android.os.Parcelable
+import com.mapbox.search.AttributeSet
+import com.mapbox.search.base.ExperimentalMapboxSearchAPI
+import com.mapbox.search.base.defaultLocaleLanguage
+import com.mapbox.search.common.IsoCountryCode
+import com.mapbox.search.common.IsoLanguageCode
+import com.mapbox.search.internal.bindgen.DetailsOptions
+import com.mapbox.search.mapToCore
+import kotlinx.parcelize.Parcelize
+
+/**
+ * Options, used for the [DetailsApi.retrieveDetails].
+ */
+@ExperimentalMapboxSearchAPI
+@Parcelize
+public class RetrieveDetailsOptions @JvmOverloads constructor(
+
+ /**
+ * Besides the basic metadata attributes, developers can request additional
+ * attributes by setting attribute_sets parameter with attribute set values,
+ * for example &attribute_sets=basic,photos,visit.
+ * The requested metadata will be provided in metadata object in the response.
+ */
+ public val attributeSets: List? = null,
+
+ /**
+ * Specify the user’s language. This parameter controls the language of the text supplied in responses.
+ * If language is not set explicitly, then language from default system locale will be used.
+ */
+ public val language: IsoLanguageCode = defaultLocaleLanguage(),
+
+ /**
+ * The ISO country code to requests a worldview for the location data,
+ * if applicable data is available.
+ * This parameters will only be applicable for Boundaries and Places feature types.
+ */
+ public val worldview: IsoCountryCode? = null,
+) : Parcelable {
+
+ /**
+ * @suppress
+ */
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (javaClass != other?.javaClass) return false
+
+ other as RetrieveDetailsOptions
+
+ if (attributeSets != other.attributeSets) return false
+ if (language != other.language) return false
+ if (worldview != other.worldview) return false
+
+ return true
+ }
+
+ /**
+ * @suppress
+ */
+ override fun hashCode(): Int {
+ var result = attributeSets?.hashCode() ?: 0
+ result = 31 * result + language.hashCode()
+ result = 31 * result + (worldview?.hashCode() ?: 0)
+ return result
+ }
+
+ /**
+ * @suppress
+ */
+ override fun toString(): String {
+ return "RetrieveDetailsOptions(" +
+ "attributeSets=$attributeSets, " +
+ "language=$language, " +
+ "worldview=$worldview" +
+ ")"
+ }
+}
+
+@OptIn(ExperimentalMapboxSearchAPI::class)
+@JvmSynthetic
+internal fun RetrieveDetailsOptions.mapToCore(): DetailsOptions {
+ return DetailsOptions(
+ attributeSets?.fixedAttributesOption()?.map { it.mapToCore() },
+ language.code,
+ worldview?.code,
+ )
+}
+
+private fun List.fixedAttributesOption(): List {
+ return if (isNotEmpty() && !contains(AttributeSet.BASIC)) {
+ this + AttributeSet.BASIC
+ } else {
+ this
+ }
+}
diff --git a/MapboxSearch/sdk/src/test/java/com/mapbox/search/details/RetrieveDetailsOptionsTest.kt b/MapboxSearch/sdk/src/test/java/com/mapbox/search/details/RetrieveDetailsOptionsTest.kt
new file mode 100644
index 000000000..8d66f3494
--- /dev/null
+++ b/MapboxSearch/sdk/src/test/java/com/mapbox/search/details/RetrieveDetailsOptionsTest.kt
@@ -0,0 +1,41 @@
+package com.mapbox.search.details
+
+import com.mapbox.search.AttributeSet
+import com.mapbox.search.base.ExperimentalMapboxSearchAPI
+import com.mapbox.search.base.core.CoreAttributeSet
+import com.mapbox.search.common.IsoCountryCode
+import com.mapbox.search.common.IsoLanguageCode
+import com.mapbox.search.common.tests.ToStringVerifier
+import nl.jqno.equalsverifier.EqualsVerifier
+import org.junit.jupiter.api.Assertions.assertEquals
+import org.junit.jupiter.api.Test
+
+@OptIn(ExperimentalMapboxSearchAPI::class)
+internal class RetrieveDetailsOptionsTest {
+
+ @Test
+ fun `Test generated equals(), hashCode() and toString() methods`() {
+ EqualsVerifier.forClass(RetrieveDetailsOptions::class.java)
+ .verify()
+
+ ToStringVerifier(RetrieveDetailsOptions::class).verify()
+ }
+
+ @Test
+ fun `Test mapToCore() function`() {
+ val options = RetrieveDetailsOptions(
+ attributeSets = listOf(AttributeSet.BASIC, AttributeSet.VISIT),
+ language = IsoLanguageCode.FRENCH,
+ worldview = IsoCountryCode.FRANCE,
+ )
+
+ val coreOptions = options.mapToCore()
+
+ assertEquals(
+ listOf(CoreAttributeSet.BASIC, CoreAttributeSet.VISIT),
+ coreOptions.attributeSets
+ )
+ assertEquals(IsoLanguageCode.FRENCH.code, coreOptions.language)
+ assertEquals(IsoCountryCode.FRANCE.code, coreOptions.worldview)
+ }
+}