[PB-5925]: add native InternxtApiClient for DocumentsProvider#422
[PB-5925]: add native InternxtApiClient for DocumentsProvider#422terrerox wants to merge 5 commits intorelease-1.9.1from
Conversation
Adds a pure-Kotlin HTTP client that talks directly to the Drive and Bridge APIs so the SAF DocumentsProvider can fetch folder contents and download links without the React Native bridge. Covers list/create/rename/move/trash on Drive (Bearer auth) and getDownloadLinks on Bridge (Basic auth with sha256(userId).hex derivation). Typed errors for 401/404/other/network; MockWebServer tests for parsing, auth headers, gateway-required headers, and error mapping.
| val clientName: String = "drive-mobile", | ||
| val clientVersion: String = "v1.9.0", |
There was a problem hiding this comment.
Perhaps we should make this configurable so that there is a single source of truth. Otherwise, we might as well forget about changing it here
| private fun driveUrl(path: String) = "${config.driveBaseUrl.trimEnd('/')}/$path".toHttpUrl() | ||
| private fun bridgeUrl(path: String) = "${config.bridgeBaseUrl.trimEnd('/')}/$path".toHttpUrl() | ||
|
|
||
| private fun execute(request: Request): JSONObject { |
There was a problem hiding this comment.
I think that this fun name could be a little more descriptive
| private fun JSONArray?.orEmpty(): JSONArray = this ?: JSONArray() | ||
|
|
||
| private inline fun <T> JSONArray.map(transform: (JSONObject) -> T): List<T> { | ||
| val out = ArrayList<T>(length()) | ||
| for (i in 0 until length()) out.add(transform(getJSONObject(i))) | ||
| return out | ||
| } | ||
|
|
||
| private fun JSONObject.optStringOrNull(key: String): String? = | ||
| if (isNull(key)) null else optString(key).takeIf { it.isNotEmpty() } | ||
|
|
||
| private fun JSONObject.optLongFlexible(key: String): Long = when (val v = opt(key)) { | ||
| is Number -> v.toLong() | ||
| is String -> v.toLongOrNull() ?: 0L | ||
| else -> 0L | ||
| } |
There was a problem hiding this comment.
Perhaps I would extract these functions and add some tests
|
|
||
| import java.security.MessageDigest | ||
|
|
||
| object HashUtil { |
There was a problem hiding this comment.
add @TamaraFinogina as codeowner for crypto directory please :)
| import org.junit.Before | ||
| import org.junit.Test | ||
|
|
||
| class InternxtApiClientTest { |
There was a problem hiding this comment.
I would add more tests, for example for listFolderFolders, createFolder, null optional fields in parseFile/parseFolder, size as a string value, and 5xx ApiError
- Wire AuthConfig.clientName/clientVersion through
BuildConfig.INTERNXT_CLIENT_NAME and BuildConfig.INTERNXT_CLIENT_VERSION,
populated by app/build.gradle from package.json. package.json is now the
single source of truth for the internxt-client/internxt-version headers.
- Extract JSON helpers (orEmpty, map, optStringOrNull, optLongFlexible)
from InternxtApiClient into JsonExtensions.kt; cover each branch in a
new JsonExtensionsTest.
- Rename InternxtApiClient.execute -> executeApiRequest.
- Expand InternxtApiClientTest: listFolderFolders, createFolder, null
optional fields, size given as a string, and 5xx -> ApiError. Add an
enqueueJson helper to cut response-stub boilerplate.
- Add @TamaraFinogina as CODEOWNER for the new documents/crypto/ directory.
…onstants in InternxtApiClientTest
|



Adds a pure-Kotlin HTTP client that talks directly to the Drive and Bridge APIs so the SAF DocumentsProvider can fetch folder contents and download links without the React Native bridge. Covers list/create/rename/move/trash on Drive (Bearer auth) and getDownloadLinks on Bridge (Basic auth with sha256(userId).hex derivation). Typed errors for 401/404/other/network; MockWebServer tests for parsing, auth headers, gateway-required headers, and error mapping.