Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add static data request #38

Merged
merged 2 commits into from
Apr 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

This is the changelog for v2 releases. See v0/v1 releases in appropriate branches.

## [2.1.0] - 2024-4-23

### Added

- Vehicle static data request

## [2.0.4] - 2024-3-14

### Added
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
version=2.0.4
version=2.1.0
kotlin.code.style=official
2 changes: 1 addition & 1 deletion gradle/deploy-ossrh.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def deployGitUrl="https://github.com/highmobility/hmkit-fleet"
def deployGroupId="com.high-mobility"
def deployLicenseName="MIT"
def deployLicenseUrl="https://opensource.org/licenses/MIT"
def deployId=name
def deployId="hmkit-fleet"

def isAndroid = project.plugins.findPlugin("com.android.library")

Expand Down
2 changes: 1 addition & 1 deletion hmkit-fleet-consumer
Original file line number Diff line number Diff line change
Expand Up @@ -135,12 +135,28 @@ class HMKitFleet constructor(
koin.get<ClearanceRequests>().deleteClearance(vin)
}

/**
* Get vehicle status JSON string from the [Vehicle Data API](https://docs.high-mobility.com/api-references/code-references/vehicle-data/reference/v1/)
*
* Read more in the [Vehicle Data API Tutorial](https://docs.high-mobility.com/guides/getting-started/rest/)
*/
fun getVehicleState(
vin: String
): CompletableFuture<Response<String>> = scope.future {
koin.get<VehicleDataRequests>().getVehicleStatus(vin)
}

/**
* Get the static information about a vehicle. Static data can include the vehicle's brand, equipment and more.
*
* Read more in the [Static Data API Tutorial](https://docs.high-mobility.com/guides/getting-started/static-data-api/)
*/
fun getVehicleStaticData(
vin: String
): CompletableFuture<Response<String>> = scope.future {
koin.get<VehicleDataRequests>().getStaticData(vin)
}

/**
* The Fleet SDK environment.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,28 @@ internal class VehicleDataRequests(
Response(responseBody, null)
}
}

suspend fun getStaticData(
vin: String,
): Response<String> {
val authToken = accessTokenRequests.getAccessToken()

if (authToken.error != null) return Response(null, authToken.error)

val request = Request.Builder()
.url("$baseUrl/vehicle-static-data/$vin")
.header("Content-Type", "application/json")
.header("Authorization", "Bearer ${authToken.response?.accessToken}")
.get()
.build()

printRequest(request)

val call = client.newCall(request)
val response = call.await()

return tryParseResponse(response, HttpURLConnection.HTTP_OK) { responseBody ->
Response(responseBody, null)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.runTest
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive
import okhttp3.mockwebserver.MockResponse
import okhttp3.mockwebserver.MockWebServer
Expand Down Expand Up @@ -145,6 +146,40 @@ class HMKitFleetTest : BaseTest() {
assertTrue(json["vin"]?.jsonPrimitive?.content == "vin1")
}

@Test
fun getVehicleStaticData() = runTest {
coEvery {
vehicleDataRequests.getStaticData("vin1")
} returns Response(
"""
{
"manufacturer": {
"brand": "Jeep",
"sub_model": "80th Anniversary Plug-In Hybrid 4WD",
"type_group_name": "Compass",
"model": "Compass (M7)(2020->)",
"sales_description": "Compass 1.3 Plug-In Hybrid (EURO 6d) 80th Annivers"
},
"equipment": {
"series_equipment": [
{
"description": "airbag driver side/passenger side",
"positions": [],
"manufacturer_id": null
}
]
}
}
""".trimIndent(),
null
)

val hmkit = HMKitFleet(oauthCredentials)
val staticData = hmkit.getVehicleStaticData("vin1").get()
val json = Json.decodeFromString<JsonObject>(staticData.response ?: "")
assertTrue(json["manufacturer"]?.jsonObject?.get("brand")?.jsonPrimitive?.content == "Jeep")
}

@Test
fun canSetCustomWebUrl() {
stopKoin()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,18 +74,18 @@ internal class VehicleDataRequestsTest : BaseTest() {
)

@Test
fun getSuccess() {
fun vehicleStatusSuccess() {
successResponses.forEach {
val responseJson = it

val mockResponse = MockResponse().setResponseCode(HttpURLConnection.HTTP_OK).setBody(responseJson)

mockWebServer.enqueue(mockResponse)
val mockUrl = mockWebServer.url("").toString()
val webService = VehicleDataRequests(client, mockLogger, mockUrl, accessTokenRequests)
val requests = VehicleDataRequests(client, mockLogger, mockUrl, accessTokenRequests)

val response = runBlocking {
webService.getVehicleStatus(testVin)
requests.getVehicleStatus(testVin)
}

coVerify { accessTokenRequests.getAccessToken() }
Expand All @@ -103,31 +103,91 @@ internal class VehicleDataRequestsTest : BaseTest() {
}

@Test
fun authTokenError() = runBlocking {
fun vehicleStatusAuthTokenError() = runBlocking {
testAuthTokenErrorReturned(mockWebServer, accessTokenRequests) { mockUrl ->
val webService = VehicleDataRequests(client, mockLogger, mockUrl, accessTokenRequests)
webService.getVehicleStatus(
val requests = VehicleDataRequests(client, mockLogger, mockUrl, accessTokenRequests)
requests.getVehicleStatus(
testVin,
)
}
}

@Test
fun requestClearanceErrorResponse() = runBlocking {
fun vehicleStatusErrorResponse() = runBlocking {
testErrorResponseReturned(mockWebServer) { mockUrl ->
val webService = VehicleDataRequests(client, mockLogger, mockUrl, accessTokenRequests)
val requests = VehicleDataRequests(client, mockLogger, mockUrl, accessTokenRequests)

webService.getVehicleStatus(
requests.getVehicleStatus(
testVin,
)
}
}

@Test
fun requestClearanceUnknownResponse() = runBlocking {
fun vehicleStatusUnknownResponse() = runBlocking {
testForUnknownResponseGenericErrorReturned(mockWebServer) { mockUrl ->
val webService = VehicleDataRequests(client, mockLogger, mockUrl, accessTokenRequests)
webService.getVehicleStatus(
val requests = VehicleDataRequests(client, mockLogger, mockUrl, accessTokenRequests)
requests.getVehicleStatus(
testVin,
)
}
}

@Test
fun vehicleStaticDataSuccess() {
successResponses.forEach {
val responseJson = it

val mockResponse = MockResponse().setResponseCode(HttpURLConnection.HTTP_OK).setBody(responseJson)

mockWebServer.enqueue(mockResponse)
val mockUrl = mockWebServer.url("").toString()
val requests = VehicleDataRequests(client, mockLogger, mockUrl, accessTokenRequests)

val response = runBlocking {
requests.getStaticData(testVin)
}

coVerify { accessTokenRequests.getAccessToken() }

val recordedRequest: RecordedRequest = mockWebServer.takeRequest()
assertTrue(recordedRequest.path!!.endsWith("/vehicle-static-data/$testVin"))

// verify request
assertTrue(recordedRequest.headers["Authorization"] == "Bearer ${authToken.accessToken}")

// verify response
val status = response.response!!
assertTrue(status == responseJson)
}
}

@Test
fun vehicleStaticDataAuthTokenError() = runBlocking {
testAuthTokenErrorReturned(mockWebServer, accessTokenRequests) { mockUrl ->
val requests = VehicleDataRequests(client, mockLogger, mockUrl, accessTokenRequests)
requests.getStaticData(
testVin,
)
}
}

@Test
fun vehicleStaticDataErrorResponse() = runBlocking {
testErrorResponseReturned(mockWebServer) { mockUrl ->
val requests = VehicleDataRequests(client, mockLogger, mockUrl, accessTokenRequests)

requests.getStaticData(
testVin,
)
}
}

@Test
fun vehicleStaticDataUnknownResponse() = runBlocking {
testForUnknownResponseGenericErrorReturned(mockWebServer) { mockUrl ->
val requests = VehicleDataRequests(client, mockLogger, mockUrl, accessTokenRequests)
requests.getStaticData(
testVin,
)
}
Expand Down
Loading